package com.iris.live.services.services.impl;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.gson.JsonObject;
import com.iris.live.services.common.*;
import com.iris.live.services.common.reconsitution.DefaultValueConstant;
import com.iris.live.services.common.reconsitution.MessageContext;
import com.iris.live.services.common.reconsitution.SendMsgRoleUtil;
import com.iris.live.services.data.models.*;
import com.iris.live.services.data.repositories.*;
import com.iris.live.services.models.PageData;
import com.iris.live.services.models.RequestBase;
import com.iris.live.services.models.ResultData;
import com.iris.live.services.report.ExcelReportContext;
import com.iris.live.services.report.IExcelReportService;
import com.iris.live.services.report.IExcelReportSource;
import com.iris.live.services.services.CarTransferService;
import com.iris.live.services.services.SalesService;
import com.iris.live.services.services.SystemService;
import org.apache.logging.log4j.ThreadContext;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException;
import org.apache.poi.ss.usermodel.Cell;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import org.springframework.util.Assert;
import org.springframework.util.StopWatch;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.persistence.PersistenceException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * Created by sxy on 2016/8/8.
 */
@Service
@Transactional // (readOnly = true)
public class SalesServiceImpl implements SalesService {

    private static Logger logger = LoggerFactory.getLogger(SalesServiceImpl.class);

    //private static Logger logdata = LoggerFactory.getLogger(SalesServiceImpl.class);
    private static Logger logdata = LoggerFactory.getLogger("Cesar");
    @Autowired
    private SalesRepository repository;

    @Autowired
    private WeekReprotRepository weekReprotRepository;

    @Autowired
    private Lsh区域Repository lsh区域Repository;


    @Autowired
    private Lsh经销商表Repository lsh经销商表Repository;

    @Autowired
    private AttachmentPolicyRepository attachmentPolicyRepository;

    @Autowired
    private DealerAttachmentPolicyRepository dealerAttachmentPolicyRepository;

    @Autowired
    private Itask基础设置Repository itask基础设置Repository;

    @Autowired
    private Lsh随车项目设置repository lsh随车项目设置Repository;

    @Autowired
    private Lsh库存表Repository lsh库存表Repository;

    @Autowired
    private Lsh库存内部可见Repository lsh库存内部可见Repository;

    @Autowired
    private SalesAdminRepository salesAdminRepository;

    @Autowired
    private 报价单表Repository i报价单表Repository;

    @Autowired
    private Lsh车型Repository lsh车型Repository;

    @Autowired
    private 报价订单表Repository i报价订单表Repository;

    @Autowired
    private 报价交车表Repository i报价交车表Repository;

    @Autowired
    private 报价客户表Repository i报价客户表Repository;

    @Autowired
    private 报价置换表Repository i报价置换表Repository;

    @Autowired
    private CarTransferLogRepository carTransferLogRepository;

    @Autowired
    private CarTransferService carTransferService;

    @Autowired
    private ExchangeStockLogRepository exchangeStockLogRepository;

    @Autowired
    private PushApprovalItemSettingRepository pushApprovalItemSettingRepository;

    @Autowired
    private 顾客记录汇总Repository 顾客记录汇总repository;

    @Autowired
    private 用户Repository 用户Repository;


    @Autowired
    private IExcelReportService excelReportService;

    @Resource(name="ExportStockSource")
    private IExcelReportSource exportStockSource;

    @Resource(name="ExportSaleTailAfter")
    private IExcelReportSource exportSaleTailAfter;

    @Resource(name = "ExportOrderSource")
    private IExcelReportSource exportOrderSource;

    @Autowired
    private 顾客进店记录表Repository repository顾客进店记录表;

    @Autowired
    private 临时接待记录Repository teampRecepRepository;

    @Autowired
    private SystemService systemService;

    @Autowired
    private FileRepository fileRepository;

    @Autowired
    private GroupAreaRepository groupAreaRepository;

    @Resource(name="ExportInventorySource")
    private IExcelReportSource exportInventorySource;

    @Resource(name = "ExportBoutiqueContract")
    private IExcelReportSource ExportBoutiqueContract;

    @Resource
    private 销售财务表Repository 销售财务表Repository;

    @Override
    public PageData getSaleList(String permit, GetSaleListRequest request) {
        return repository.getSaleList(permit, request);
    }

    @Override
    public Lsh经销商表Model saveDealer(Lsh经销商表Model model) {
        Assert.notNull(model);
        Assert.hasLength(model.getBmbs());
        return this.lsh经销商表Repository.save(model);
    }

    @Override
    public List<Lsh经销商表Model> saveDealerBatch(List<Lsh经销商表Model> modelList) {
        Assert.notNull(modelList);
        return this.lsh经销商表Repository.save(modelList);
    }

    @Override
    public AttachmentPolicyModel saveAttachmentPolicy(AttachmentPolicyModel model) {
        Assert.notNull(model);
        return this.attachmentPolicyRepository.save(model);
    }

    @Override
    public List<AttachmentPolicyModel> saveAttachmentPolicyBatch(List<AttachmentPolicyModel> modelList) {
        Assert.notNull(modelList);
        return this.attachmentPolicyRepository.save(modelList);
    }

    @Override
    public boolean saveAttachmentPolicyStatus(String siProgramCodeEnglish, String siTypeDescription, String status) {
        int result = this.attachmentPolicyRepository
                .setSiStatusBySiProgramCodeEnglishAndSiTypeDescription(siProgramCodeEnglish, siTypeDescription, status);
        return true;
    }

    @Override
    public DealerAttachmentPolicyModel saveDealerAttachmentPolicy(DealerAttachmentPolicyModel model) {
        Assert.notNull(model);
        return this.dealerAttachmentPolicyRepository.save(model);
    }

    @Override
    public List<DealerAttachmentPolicyModel> saveDealerAttachmentPolicyBatch(
            List<DealerAttachmentPolicyModel> modelList) {
        Assert.notNull(modelList);
        return this.dealerAttachmentPolicyRepository.save(modelList);
    }

    @Override
    public boolean saveDealerAttachmentPolicyStatus(String permit, Integer dealerSiNumber, String status) {
        int result = this.dealerAttachmentPolicyRepository.setStatusByPermitAndDealerSiNumber(permit, dealerSiNumber,
                status);
        return true;
    }

    @Override
    public PageData getCarItemList(String permit, RequestBase request) {
        return repository.getCarItemList(permit, request);
    }

    @Override
    public PageData getAttachmentPolicyList(String permit, GetAttachmentPolicyListRequest request) {
        return repository.getAttachmentPolicyList(permit, request);
    }

    @Override
    public PageData getAttachmentPolicyListByCondition(String permit, GetAttachmentPolicyListReq request) {
        return repository.getAttachmentPolicyListByCondition(permit, request);
    }

    @Override
    public Itask基础设置Model saveBasicSetting(Itask基础设置Model model) {
        Assert.notNull(model);
        return this.itask基础设置Repository.save(model);
    }

    @Override
    public List<Itask基础设置Model> saveBasicSettingBatch(List<Itask基础设置Model> modelList) {
        Assert.notNull(modelList);
        DecimalFormat df = new DecimalFormat("#0.0000");
        //后台存储的格式为：
        // 设置项目：数据库手续费统一格式为：（1）上牌服务费成本（2）其他一成本（3）其他二成本
        // 值的格式为： 成本__5000.00   比例__0.3333
        // 通过 成本__和 比例__ 来区分  服务费成本 和 服务费成本比例
        for (Itask基础设置Model mode:modelList) {

            Itask基础设置Model Dao = new Itask基础设置Model();
            Dao.set更新时间(DateFormatUtils.getFormatTimestamp("yyyy-MM-dd HH:mm:ss", new Date()));
            if ("上牌服务费成本".equals(mode.get设置项目()) || "上牌服务费成本比例".equals(mode.get设置项目())){

                Dao.set更新账号(mode.get更新账号());
                Dao.set许可(mode.get许可());

                if ("上牌服务费成本".equals(mode.get设置项目())){
                    Dao.set值("成本__"+mode.get值());
                }else{
                   Double dou = Double.parseDouble(mode.get值())/100;
                    Dao.set值("比例__"+df.format(dou));
                }
                Dao.set设置项目("上牌服务费成本");
            }else if ("其他一成本".equals(mode.get设置项目()) || "其他一成本比例".equals(mode.get设置项目())){

                Dao.set更新账号(mode.get更新账号());
                Dao.set许可(mode.get许可());

                if ("其他一成本".equals(mode.get设置项目())){
                    Dao.set值("成本__"+mode.get值());
                }else{
                    Double dou = Double.parseDouble(mode.get值());
                    dou = dou/100;
                    Dao.set值("比例__"+df.format(dou));
                }
                Dao.set设置项目("其他一成本");
            }else if ("其他二成本".equals(mode.get设置项目()) || "其他二成本比例".equals(mode.get设置项目())){

                Dao.set更新账号(mode.get更新账号());
                Dao.set许可(mode.get许可());

                if ("其他二成本".equals(mode.get设置项目())){
                    Dao.set值("成本__"+mode.get值());
                }else{
                    Double dou = Double.parseDouble(mode.get值())/100;
                    Dao.set值("比例__"+df.format(dou));
                }
                Dao.set设置项目("其他二成本");
            }
            itask基础设置Repository.save(Dao);
        }
        return modelList;
    }

    @Override
    public Lsh随车项目设置Model saveCarItemSetting(Lsh随车项目设置Model model) {
        Assert.notNull(model);
        return lsh随车项目设置Repository.save(model);
    }

    @Override
    public List<Lsh随车项目设置Model> saveCarItemSettingBatch(List<Lsh随车项目设置Model> modelList) {
        Assert.notNull(modelList);
        return lsh随车项目设置Repository.save(modelList);
    }

    @Override
    public PageData getActiveCarItemSettingList(String permit, GetCarItemSettingRequest request) {
        return repository.getActiveCarItemSettingList(permit, request);
    }

    @Override
    @Transactional
    public boolean saveSalesAdminModelBatch(List<Lsh销售行政Model> modelList) {
        /*
         * 1. 根据VIN查找库存表，决定Lsh销售行政Model是更新还是新增 2. 如果是新增 2.1 增加车型表 2.2 增加库存表 2.3
		 * 增加库存表 4. 增加库存表
		 */
        for (Lsh销售行政Model model : modelList) {
            String vin = model.get车架号();
            Lsh库存表Model lsh库存表M = findLsh库存表ByVin(vin);
            boolean isUpdate;
            if (lsh库存表M == null) { // 保存
                isUpdate = false;
                Lsh车型Model lsh车型Model = saveLsh车型(model, isUpdate, null);
                Lsh库存表Model lsh库存表Model = saveLsh库存表(model, isUpdate, null, lsh车型Model.get车型编号());
                // SalesAdminModel salesAdminModel = saveSalesAdmin(model,
                // isUpdate, lsh库存表Model.get车架号());
                // 报价客户表Model 报价客户表Model = save报价客户表(model, isUpdate, null);
                // 报价置换表Model 报价置换表Model = save报价置换表(model, isUpdate, null);
                // 报价交车表Model 报价交车表Model = save报价交车表(model, isUpdate, null);
                // 报价订单表Model 报价订单表Model = save报价订单表(model, isUpdate, null);
                // 报价单表Model 报价单表Model = save报价单表(model, isUpdate,
                // lsh库存表Model.get库存编号(), 报价客户表Model.get编号(),
                // 报价置换表Model.get置换编号(), lsh车型Model.get车型编号(),
                // 报价订单表Model.get订单编号(), 报价交车表Model.get编号());
            } else { // 更新
                isUpdate = true;
                Lsh车型Model lsh车型Model = saveLsh车型(model, isUpdate, lsh库存表M.get车型编号());
                Lsh库存表Model lsh库存表Model = saveLsh库存表(model, isUpdate, lsh库存表M.get库存编号(), null);
                // SalesAdminModel salesAdminModel = saveSalesAdmin(model,
                // isUpdate, lsh库存表Model.get车架号());
                // 报价单表Model 报价单表Model = save报价单表(model, isUpdate,
                // lsh库存表Model.get库存编号(), null, null, null, null, null);
                // 报价客户表Model 报价客户表Model = save报价客户表(model, isUpdate,
                // 报价单表Model.get客户详细());
                // 报价置换表Model 报价置换表Model = save报价置换表(model, isUpdate,
                // 报价单表Model.get置换编号());
                // 报价交车表Model 报价交车表Model = save报价交车表(model, isUpdate,
                // 报价单表Model.get交车());
                // 报价订单表Model 报价订单表Model = save报价订单表(model, isUpdate,
                // 报价单表Model.get订单编号());
            }

			/*
             * Lsh车型Model lsh车型Model = saveLsh车型(model, isUpdate, lsh车型编号);
			 *
			 * Lsh库存表Model lsh库存表Model = saveLsh库存表(model,
			 * lsh车型Model.get车型编号());
			 *
			 * save报价单表(model); saveLsh库存表(model); saveSalesAdmin(model);
			 */
        }

        return true;
    }

    private Lsh库存表Model findLsh库存表ByVin(String vin) {
        final String vin1 = vin;

        // 根据VIN查找Lsh库存表
        Specification<Lsh库存表Model> specification = new Specification<Lsh库存表Model>() {
            @Override
            public Predicate toPredicate(Root<Lsh库存表Model> root, CriteriaQuery<?> criteriaQuery,
                                         CriteriaBuilder criteriaBuilder) {
                Predicate predicate = criteriaBuilder.conjunction();
                predicate.getExpressions().add(criteriaBuilder.equal(root.<Lsh库存表Model>get("车架号"), vin1));
                return predicate;
            }

            ;
        };
        List<Lsh库存表Model> Lsh库存表list = lsh库存表Repository.findAll(specification);

        if (Lsh库存表list != null && Lsh库存表list.size() > 0) {
            return Lsh库存表list.get(0);
        } else {
            return null;
        }
    }

    private Lsh库存表Model saveLsh库存表(Lsh销售行政Model model, boolean isUpdate, Integer lsh库存编号, Integer lsh车型编号) {
        Lsh库存表Model lsh库存表Model;
        if (isUpdate) {
            lsh库存表Model = lsh库存表Repository.findOne(lsh库存编号);
        } else {
            lsh库存表Model = new Lsh库存表Model();
            lsh库存表Model.set车型编号(lsh车型编号);
        }
        model.setLsh库存表Model(lsh库存表Model);
        return lsh库存表Repository.save(model.getLsh库存表Model());

    }

    private SalesAdminModel saveSalesAdmin(Lsh销售行政Model model, boolean isUpdate, String vin) {
        SalesAdminModel salesAdminModel;
        if (isUpdate) {
            salesAdminModel = salesAdminRepository.findOne(vin);
        } else {
            salesAdminModel = new SalesAdminModel();
            salesAdminModel.setVin(vin);
        }
        model.setSalesAdminModel(salesAdminModel);

        return salesAdminRepository.save(model.getSalesAdminModel());
    }

    private 报价单表Model save报价单表(Lsh销售行政Model model, boolean isUpdate, Integer lsh库存编号, Integer lsh客户详细, Integer lsh置换编号,
                               Integer lsh车型编号, Integer lsh订单编号, Integer lsh交车) {
        报价单表Model 报价单表Model;
        if (isUpdate) {
            报价单表Model = i报价单表Repository.findOne(lsh库存编号);
        } else {
            报价单表Model = new 报价单表Model();
            报价单表Model.set库存编号(lsh库存编号);
            报价单表Model.set客户详细(lsh客户详细);
            报价单表Model.set置换编号(lsh置换编号);
            报价单表Model.set订单编号(lsh订单编号);
            报价单表Model.set车型编号(lsh车型编号);
            报价单表Model.set交车(lsh交车);
        }
        model.set报价单表Model(报价单表Model);

        return i报价单表Repository.save(model.get报价单表Model());
    }

    private Lsh车型Model saveLsh车型(Lsh销售行政Model model, boolean isUpdate, Integer lsh车型编号) {
        Lsh车型Model lsh车型Model;
        if (isUpdate) {
            lsh车型Model = lsh车型Repository.findOne(lsh车型编号);
        } else {
            lsh车型Model = new Lsh车型Model();
        }
        model.setLsh车型Model(lsh车型Model);
        Lsh车型Model sh = model.getLsh车型Model();
        return sh;
    }

    private 报价订单表Model save报价订单表(Lsh销售行政Model model, boolean isUpdate, Integer lsh订单编号) {
        报价订单表Model 报价订单表Model;
        if (isUpdate) {
            报价订单表Model = i报价订单表Repository.findOne(lsh订单编号);
        } else {
            报价订单表Model = new 报价订单表Model();
        }
        model.set报价订单表Model(报价订单表Model);

        return i报价订单表Repository.save(model.get报价订单表Model());
    }

    private 报价交车表Model save报价交车表(Lsh销售行政Model model, boolean isUpdate, Integer lsh交车编号) {
        报价交车表Model 报价交车表Model;
        if (isUpdate) {
            报价交车表Model = i报价交车表Repository.findOne(lsh交车编号);
        } else {
            报价交车表Model = new 报价交车表Model();
        }
        model.set报价交车表Model(报价交车表Model);

        return i报价交车表Repository.save(model.get报价交车表Model());
    }

    private 报价客户表Model save报价客户表(Lsh销售行政Model model, boolean isUpdate, Integer lsh报价客户编号) {
        报价客户表Model 报价客户表Model;
        if (isUpdate) {
            报价客户表Model = i报价客户表Repository.findOne(lsh报价客户编号);
        } else {
            报价客户表Model = new 报价客户表Model();
        }
        model.set报价客户表Model(报价客户表Model);

        return i报价客户表Repository.save(model.get报价客户表Model());
    }

    private 报价置换表Model save报价置换表(Lsh销售行政Model model, boolean isUpdate, Integer lsh置换编号) {
        报价置换表Model 报价置换表Model;
        if (isUpdate) {
            报价置换表Model = i报价置换表Repository.findOne(lsh置换编号);
        } else {
            报价置换表Model = new 报价置换表Model();
        }
        model.set报价置换表Model(报价置换表Model);

        return i报价置换表Repository.save(model.get报价置换表Model());
    }

    @Override
    public PageData getDealerInfo(String dealer, Map map, RequestBase request) {

//        PageData pageDate = repository.getDealerInfo(dealer, map, request);
//        List list = pageDate.getData();
//        for (int i = 0; i < list.size(); i++) {
//            Map map2 = (Map) list.get(i);
//            String vin = (String) map2.get("车架号（VIN）");
//            Map map3 = Maps.newHashMap();
//            if (vin != null && !"".equals(vin)) {
//                map3 = apiForLiveService.getGPByVin(vin);
//            } else {
//                map3.put("SalesTGP", "");
//                map3.put("SalesTGPRate", "");
//                map3.put("GP1", "");
//                map3.put("GP1Rate", "");
//                map3.put("GP2", "");
//                map3.put("GP2Rate", "");
//                map3.put("GP3", "");
//                map3.put("GP3Rate", "");
//            }
//            map2.put("GP1", map3.get("GP1"));
//            map2.put("GP1%", map3.get("GP1Rate"));
//            map2.put("GP2", map3.get("GP2"));
//            map2.put("GP2%", map3.get("GP2Rate"));
//            map2.put("GP3", map3.get("GP3"));
//            map2.put("GP3%", map3.get("GP3Rate"));
//            map2.put("SalesTGP%", map3.get("SalesTGPRate"));
//            map2.put("SalesTGP", map3.get("SalesTGP"));
//        }
//        return pageDate;
        return repository.getStoreInfoes(dealer, map, request);
    }

    @Override
    public void exportStockInfo(String dealer, Map map, RequestBase request, OutputStream outputStream) {
        try {
            ExcelReportContext context = new ExcelReportContext();
            String[] columns = map.get("columns").toString().split("[|]");
            map.remove("columns");
            if("01".equals(map.get("car_state"))){//兼容新的销售行政
            context.setTemplate("templates/销售行政已归档交车导入模版.xlsx")
                    .setFileName("销售行政已归档交车导入模版.xlsx");}
             else{
                context.setTemplate("templates/销售行政标准导出模板.xlsx")
                        .setFileName("销售行政标准导出模板.xlsx");
            }
            context .setSource(exportStockSource)
                    .setStaticSheet(false)
                    .setStartCellIndex(0)
                    .setEndCellIndex(columns.length)
                    .setAutoRowExtended(true)
                    .addParam("dealer", dealer)
                    .addParam("param", map)
                    .addParam("columns", columns)
                    .addParam("request", request);

            excelReportService.export(context, outputStream);
        } catch (Exception e) {
            logger.error("导出线索信息异常", e);
        }
    }

    @Override
    public PageData getOtherDealerInfo(String dealer, Map map, RequestBase request) {
        PageData pageDate = repository.getOtherDealerInfo(dealer, map, request);
        return pageDate;
    }

    @Override
    public PageData getOtherStoreCar(GetOtherStoreCarReq request) {
        return repository.getOtherStoreCar(request);
    }

    @Override
    public List SelectCarTransferLog(String VIN, String type) {
        return repository.SelectCarTransferLog(VIN, type);
    }

//    @Override
//    @Transactional
//    public boolean updateCustInfoByVIN(UpdateCustInfoByVINReq req) {
//        if (Strings.isNullOrEmpty(req.VIN)) {
//            return false;
//        }
//        try {
//            int a = lsh库存表Repository.updateByVIN(req.VIN, req.guest, req.reason, req.amount);
//            int b = salesAdminRepository.updateByVIN(req.VIN, req.ownerOrDrawerName, req.expectedLateInStockDate,
//                    req.expectedLateMoneyInAccount);
//            if (a == 1 && b == 1) {
//                int c = 1 / 0; // 如果没有更新两个表，制造异常抛出
//            }
//        } catch (Exception e) {
//            logger.error("运行异常。", e);
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            return false;
//        }
//        return true;
//    }

    @Override
    public List getNoReceiptProNo(String permit) {
        return repository.getNoReceiptProNo(permit);
    }

    @Override
    public List getCompareModelsList() {
        return repository.getCompareModelsList();
    }

    @Override
    @Transactional
    public ResultData saveLshStock(List<SaveLshStockReq> reqList, String operaAcct, String permit) {
        int count = 0;
        ResultData resultData = new ResultData();
        resultData.setResult("true");
        resultData.setMessage("正常");
        // 根据生产号，车架号找出库里的数据
        List prodList = repository.getExistProductNo(reqList);
        Map<Object, List> prodMap = new HashMap<>();
        for (Object o : prodList) {
            Map m = (Map) o;
            List<Object> l = new ArrayList<>();
            l.add(0, m.get("库存编号"));
            l.add(1, m.get("生产号"));
            l.add(2, m.get("车架号"));
            l.add(3, m.get("开票时间"));
            l.add(4, m.get("调车物流状态"));
            l.add(5, m.get("出库日期"));
            l.add(6, m.get("二次PDI完成日期"));
            l.add(7, m.get("入库日期"));
            l.add(8, m.get("批发日期"));
            prodMap.put(m.get("生产号"), l);
        }
        List vinList = repository.getExistVin(reqList);
        Map<Object, List> vinMap = new HashMap<>();
        for (Object o : vinList) {
            Map m = (Map) o;
            List<Object> l = new ArrayList<>();
            l.add(0, m.get("库存编号"));
            l.add(1, m.get("生产号"));
            l.add(2, m.get("车架号"));
            l.add(3, m.get("开票时间"));
            l.add(4, m.get("调车物流状态"));
            l.add(5, m.get("出库日期"));
            l.add(6, m.get("二次PDI完成日期"));
            l.add(7, m.get("入库日期"));
            l.add(8, m.get("批发日期"));
            vinMap.put(m.get("车架号"), l);
        }
        boolean isShow = repository.getIsShow(permit);
        List<Lsh库存表Model> reInsertList = new ArrayList<>(500);
        List<Lsh库存表Model> reUpdateList = new ArrayList<>(500);
        // excel中的生产号不属于本店时，更新所属经销商 -- 小廖的说法  byDF 20161224
        // 根据不同的情况处理数据
        for (SaveLshStockReq req : reqList) {
            // 库中不存在该生产号
            if (!prodMap.containsKey(req.productNo)) {
                // req.vin非null且库中存在相同的vin码时，作为不合法输入处理
                if (req.VIN != null && vinMap.containsKey(req.VIN)) {
                    resultData.setResult("false");
                    resultData.setMessage(String.format("车架号：%s，在系统中已经存在，请检查EXCEL中该车架号与生产号是否正确，如果正确请联系售后", req.VIN));
                    return resultData;
                } else {
                    // req.vin为null，或库中不存在重复的vin码时，作为新车入库
                    req.status = getCarTransportStatus(req.status, req.startProduDate, Arrays.asList(null, null, null, null));
                    Lsh库存表Model model = constructInsertCarStockModel(permit, req, operaAcct, ++count);
                    reInsertList.add(model);
                }
            } else {
                // 库中存在该生产号
                // req.vin为null时，不管以前是什么值，将vin修改为虚拟车架号，传入库存编号，更新记录
                if (req.VIN == null) {
                    List temp = prodMap.get(req.productNo);
                    // 库中该车非开票且非调车状态时，更新
                    if (temp.get(3) == null && temp.get(4) == null) {
                        req.status = getCarTransportStatus(req.status, req.startProduDate, Arrays.asList(temp.get(5), temp.get(6), temp.get(7), temp.get(8)));
                        Lsh库存表Model model = constructUpdateCarStockModel(permit, (Integer) temp.get(0), req);
                        reUpdateList.add(model);
                    }
                } else {
                    // req.vin非null
                    // 库中存在相同的vin码
                    if (vinMap.containsKey(req.VIN)) {
                        // 两条数据库存编号相同，更新记录
                        if (prodMap.get(req.productNo).get(0).equals(vinMap.get(req.VIN).get(0))) {
                            List temp = prodMap.get(req.productNo);
                            // 库中该车非开票且非调车状态时，更新
                            if (temp.get(3) == null && temp.get(4) == null) {
                                req.status = getCarTransportStatus(req.status, req.startProduDate, Arrays.asList(temp.get(5), temp.get(6), temp.get(7), temp.get(8)));
                                Lsh库存表Model model = constructUpdateCarStockModel(permit, (Integer) temp.get(0), req);
                                reUpdateList.add(model);
                            }
                        } else {
                            // 两条数据库存编号不同，作为不合法输入处理
                            resultData.setResult("false");
                            resultData.setMessage(String.format("车架号：%s，在系统中已经存在，请检查EXCEL中该车架号与生产号是否正确，如果正确请联系售后", req.VIN));
                            return resultData;
                        }
                    } else {
                        // 库中不存在相同的vin码，更新数据
                        List temp = prodMap.get(req.productNo);
                        // 库中该车非开票且非调车状态时，更新
                        if (temp.get(3) == null && temp.get(4) == null) {
                            req.status = getCarTransportStatus(req.status, req.startProduDate, Arrays.asList(temp.get(5), temp.get(6), temp.get(7), temp.get(8)));
                            Lsh库存表Model model = constructUpdateCarStockModel(permit, (Integer) temp.get(0), req);
                            reUpdateList.add(model);
                        }
                    }
                }
            }
        }
        // 保存后，reInsertList中的库存编号就有值了
        lsh库存表Repository.save(reInsertList);
        insertStock(  reInsertList,  permit,  operaAcct);
        resultData.setMessage(String.format("成功更新%s条数据，添加%s条数据", reUpdateList.size(), reInsertList.size()));
        lsh库存表Repository.save(reUpdateList);
        return resultData;
    }

    /*
     * 根据excel记录与其相匹配的库里的记录，计算车辆物流状态
     * @param excelStatus 导入excel表当前记录的物流状态
     * @param excelProdStartDate 导入excel表当前记录生产期开始
     * @param dateList 当前匹配生产号与车架号的日期列表，出库日期，二次PDI完成日期，入库日期，批发日期
     * @return 车辆物流状态
     */
    private String getCarTransportStatus(String excelStatus, Date excelProdStartDate, List dateList) {
        // 出库日期
        Date outerDate = (Date) dateList.get(0);
        // 二次PDI完成日期
        Date secondPDIDate = (Date) dateList.get(1);
        // 入库日期
        Date innerDate = (Date) dateList.get(2);
        // 批发日期
        Date batchDate = (Date) dateList.get(3);
        String status;
        Date date = new Date();
        if (outerDate != null && outerDate.before(date)) {
            status = "出库";
        } else if (secondPDIDate != null) {
            status = "二次PDI_OK";
        } else if (innerDate != null) {
            status = "车辆到店";
        } else if (batchDate != null && batchDate.before(date)) {
            status = "已批发";
            // LVIC，LVRD，LOIR，LMDU，LVRD
        } else if (excelStatus != null && "LVIC".equalsIgnoreCase(excelStatus)
                || "LVRD".equalsIgnoreCase(excelStatus)
                || "LOIR".equalsIgnoreCase(excelStatus)
                || "LMDU".equalsIgnoreCase(excelStatus)
                || "LVRD".equalsIgnoreCase(excelStatus)) {
            status = "VPC";
            // LVDP，LPOC
        } else if (excelStatus != null && "LVDP".equalsIgnoreCase(excelStatus)
                || "LPOC".equalsIgnoreCase(excelStatus)) {
            status = "在海上";
        } else if (excelProdStartDate != null && excelProdStartDate.before(date)) {
            status = "生产中";
        } else {
            status = "已下生产订单";
        }
        return status;
    }

    /*
     * 更新库存表记录的方法
     * @param permit 许可
     * @param stockId 库存编号
     * @param req 请求json
     * @return 准备更新的model
     */
    private Lsh库存表Model constructUpdateCarStockModel(String permit, Integer stockId, SaveLshStockReq req) {
        // 廖总 11.28 要求更改
        Lsh库存表Model model = lsh库存表Repository.findOne(stockId);
        if (!"".equals(req.productNo) && req.productNo != null) {
            model.set生产号(req.productNo);
        }
        if (req.carNo != null) {
            model.set车型编号(req.carNo);
        }
        if (req.proDate != null) {
            model.set生产日期(req.proDate);
        }
        if (!"".equals(req.VIN) && req.VIN != null) {
            model.set车架号(req.VIN);
        }
        if (!"".equals(req.chassisNo) && req.chassisNo != null) {
            model.set欧版底盘号(req.chassisNo);
        }
        if (!"".equals(req.engineNo) && req.engineNo != null) {
            model.set发动机号(req.engineNo);
        }
        if (!"".equals(req.VSB) && req.VSB != null) {
            model.setVsb号(req.VSB);
        }
        if (!"".equals(req.colorCode) && req.colorCode != null) {
            model.set颜色代码(req.colorCode);
        }
        if (!"".equals(req.color) && req.color != null) {
            model.set颜色(req.color);
        }
        if (!"".equals(req.innerCode) && req.innerCode != null) {
            model.set内饰代码(req.innerCode);
        }
        if (!"".equals(req.inner) && req.inner != null) {
            model.set内饰(req.inner);
        }
        if (!"".equals(req.factoryConfig) && req.factoryConfig != null) {
            model.set原厂配置(req.factoryConfig);
        }
        if (!"".equals(req.addConfig) && req.addConfig != null) {
            model.set加配配置(req.addConfig);
        }
        if (req.addConfigPrice != null) {
            model.set加配价格含税(req.addConfigPrice);
        }
        if (req.buyPriceTax != null) {
            model.set采购价格含税(req.buyPriceTax);
        }
        if (req.buyPrice != null) {
            model.set采购价格未税(req.buyPrice);
        }
        if (req.factMSRPTax != null) {
            model.set实际Msrp含税(req.factMSRPTax);
        }
        if (req.orderDate != null) {
            model.set厂家确认订单日期(req.orderDate);
        }
        if (req.standardMSRPTax != null) {
            model.set标配Msrp含税(req.standardMSRPTax);
        }
        if (req.orderDate != null) {
            model.set厂家确认订单日期(req.orderDate);
        }
        if (req.expectRollDate != null) {
            model.set预计下线日期(req.expectRollDate);
        }
        if (!"".equals(req.status) && req.status != null) {
            model.set车辆物流状态(req.status);
        }
        if (!"".equals(req.wholesaler) && req.wholesaler != null) {
            model.set批发商(req.wholesaler);
        }
        // 新添加的字段，归档状态，默认“00”表示未归档
        model.setCarState("00");
        model.set所属经销商(permit);
        return model;
    }

    /*
     * 向库存表中添加新记录
     * @param permit 许可
     * @param req 请求json
     * @param isShow
     * @param operaAcct
     * @return
     */
    private Lsh库存表Model constructInsertCarStockModel(String permit, SaveLshStockReq req, String operaAcct, int count) {
        Lsh库存表Model model = new Lsh库存表Model();
        model.set生产号(req.productNo);
        model.set车型编号(req.carNo);
        model.set生产日期(req.proDate);
        String str1[] = operaAcct.split("@");
        String str2 = "Email";
        if (str1.length > 0) {
            str2 = str1[0];
            if (str2.length() > 18) {
                str2 = str2.substring(0, 18);
            }
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String currentTime = sdf.format(new Date());
        // IRISTechNV_'+操作账号@左侧部分(如果没有@,账号取'Email',如果取完长度大于18个字符，则取左侧18个字符)+年月日时分秒+本次导入的序号
        String VIN = "";
        if (req.VIN != null) {
            VIN = req.VIN;
        } else {
            ++count;
            VIN = "IRISTechNV_" + str2 + "_" + currentTime + "_" + count;
        }
        model.set车架号(VIN);
        model.set欧版底盘号(req.chassisNo);
        model.set发动机号(req.engineNo);
        model.setVsb号(req.VSB);
        model.set颜色代码(req.colorCode);
        model.set颜色(req.color);
        model.set内饰代码(req.innerCode);
        model.set内饰(req.inner);
        model.set原厂配置(req.factoryConfig);
        model.set加配配置(req.addConfig);
        model.set加配价格含税(req.addConfigPrice);
        model.set采购价格含税(req.buyPriceTax);
        model.set采购价格未税(req.buyPrice);
        model.set实际Msrp含税(req.factMSRPTax);
        model.set厂家确认订单日期(req.orderDate);
        model.set标配Msrp含税(req.standardMSRPTax);
        model.set预计下线日期(req.expectRollDate);
        model.set车辆物流状态(req.status);
        model.set批发商(req.wholesaler);
        model.set采购批发商(permit);
        // 新添加的字段，归档状态，默认“00”表示未归档
        model.setCarState("00");

        //默认外部可见级别'外部不可见',所属经销商：许可。??
        Itask基础设置ModelPK pkson = new Itask基础设置ModelPK();
        pkson.set许可(permit);
        pkson.set设置项目("本店车辆他店可见级别");
        Itask基础设置Model bigCitypermit = itask基础设置Repository.findOne(pkson);
        if (bigCitypermit != null) {
            String zhi = bigCitypermit.get值();
            if (zhi != null) {
                if (zhi.equals("0")) {
                    model.set外部可见级别("全国可见");
                } else if (zhi.equals("1")) {
                    model.set外部可见级别("大区可见");
                } else if (zhi.equals("2")) {
                    model.set外部可见级别("小区可见");
                } else if (zhi.equals("3")) {
                    model.set外部可见级别("CTA可见");
                } else if (zhi.equals("4")) {
                    model.set外部可见级别("外部不可见");
                } else {
                    model.set外部可见级别("外部不可见");
                }
            } else {
                model.set外部可见级别("外部不可见");
            }
        } else {
            model.set外部可见级别("外部不可见");
        }
        // model.set外部可见级别("外部不可见");
        model.set所属经销商(permit);
        model.set车辆零售状态("未卖");
        return model;
    }

//    @Override
//    public boolean updateByStockNo(UpdateByStockNoReq request) {
//        int a = lsh库存表Repository.updateByStockNo(request.stockNo, request.guest, request.reason, request.amount);
//        return a > 0 ? true : false;
//    }

    @Override
    public Map getTransferCustInfo(Integer stock_code) {
        return repository.getTransferCustInfo(stock_code);
    }

//    @Override
//    @Transactional
//    public boolean addTransferCustInfo(CarTransferLogModel model) {
//        try {
//            //先判断是否存在，如果存在先删除，在执行新增
//            boolean flag = repository.checkExistByStockCode(model.getStockCode());
//            if (flag) {
//                carTransferLogRepository.deletByStockCode(model.getStockCode());
//            }
//            carTransferLogRepository.save(model);
//        } catch (Exception e) {
//            logger.error("运行异常。", e);
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            return false;
//        }
//        return true;
//    }

//    @Override
//    @Transactional
//    public boolean updateByStockCode(UpdateByStockCodeReq req) {
//        Timestamp ts = DateFormatUtils.getFormatTimestamp("yyyy-MM-dd HH:mm:ss", new Date());
//        int a = carTransferLogRepository.updateByStockCode(req.stock_code, req.stock_out_date, req.stock_out_user, ts);
//        return a > 0 ? true : false;
//    }

    @Override
    @Transactional
    public List selectExistNum(List<Lsh库存表Model> modelList) {
        List list = new ArrayList();
        for (int i = 0; i < modelList.size(); i++) {
            for (Lsh库存表Model model : modelList) {
                //如果没有找到+1
                if (!repository.selectExistNum(model.get生产号())) {
                    list.add(model.get生产号());
                }
            }
        }
        return list;
    }

    @Override // 需要 将 置 null 的 改变  xxd
    @Transactional
    public int addLshStockTable(List<Lsh库存表Model> modelList) {
        int num = 0;
        for (Lsh库存表Model model : modelList) {
            //查询表中是否存在相同生产号的记录，找到后更新否则不做任何处理。
            Lsh库存表Model tempModel = lsh库存表Repository.findLshRecordByProId(model.get生产号());
            // 前台传过来的 list---有生产号》》》得到  如果 原数据库 里面 有  那么 你就更新这条数据
            if (tempModel != null) {
                Date proDate = model.get批发日期();
                Date proDate2 = tempModel.get批发付款到期日();

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                // 其中 如果 更新时 遇到了  你原有的 批发付款到期日 为空 那么 以 传过来的批发日期+15
                if (proDate2 == null || "0000-00-00".equals(sdf.format(proDate2))) {
                    Calendar cal = Calendar.getInstance();
                    if (!"".equals(model.get批发日期()) && model.get批发日期() != null) {
                        cal.setTime(proDate);
                        cal.add(Calendar.DATE, 15);
                        tempModel.set批发付款到期日(cal.getTime());
                    }// 小廖 要求的 逻辑 必须 是 传入的 批发日期 和 数据库原始 没有批发付款到期日 同时存在 才会 批发付款到期日 +15
                }
                //11.15 xxd 修改，如果 没有 传入的 批发日期，那么 直接 把库龄天数 保存
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                long day = 0;
                Date endDate = new Date();

                if (model.get批发日期() != null) {
                    day = (endDate.getTime() - model.get批发日期().getTime()) / (24 * 60 * 60 * 1000);
                    tempModel.set库龄天数(new Long(day).intValue());
                }

                // 把传过来的 四条数据 更新
                tempModel.set港口代码(model.get港口代码());
                tempModel.set实际到港日期(model.get实际到港日期());
                tempModel.set预计到港日期(model.get预计到港日期());
                tempModel.set批发日期(model.get批发日期());

                lsh库存表Repository.save(tempModel);
                num++;
            }
        }
        return num;
    }

    @Override
    @Transactional
    public boolean updateNbiCarStatus(String permit) throws ParseException {
        Calendar cal = Calendar.getInstance();
        int month = cal.get(Calendar.MONTH) + 1;
        int year = cal.get(Calendar.YEAR);
        cal.set(year, month - 1, 20);  //当月20号
        Date strTwintyDay = cal.getTime();

        cal.set(Calendar.DATE, 1);//把日期设置为当月第一天
        cal.roll(Calendar.DATE, -1);//日期回滚一天，也就是最后一天
        int maxDate = cal.get(Calendar.DATE);
        cal.set(year, month - 1, maxDate - 2);
        Date strLastThree = cal.getTime();  //当月倒数第三天

        //1.查询出 本许可的lsh库存表 并且 nbi车辆状态不是“现货库存”的库存
        List<Lsh库存表Model> list = lsh库存表Repository.getCarsNotPresent(permit);

        //2.遍历list，更改nbi车辆状态
        for (Lsh库存表Model e : list) {
            Date date1980 = new SimpleDateFormat("yyyy-MM-dd 00:00:00").parse("1980-01-01 00:00:00");
            //如果入库日期不为空
            if (e.get入库日期() != null) {
                //2.1 如果入库日期大于1980-01-01 00:00:00，更改nbi车辆状态为“现货库存”
                if (DateFormatUtils.getFormatDate("yyyy-MM-dd HH:mm:ss", e.get入库日期()).getTime() > date1980.getTime()) {
                    e.setNbi车辆状态("现货库存");
                    continue;
                }
            }
            //如果入库日期为空，当做入库日期小于1980-01-01 00:00:00 执行下一步
            //2.2 如果批发日期大于1980-01-01 00:00:00，更改nbi车辆状态为“在途库存”
            if (e.get批发日期() != null) {
                if (DateFormatUtils.getFormatDate("yyyy-MM-dd HH:mm:ss", e.get批发日期()).getTime() > date1980.getTime()) {
                    e.setNbi车辆状态("在途库存");
                    continue;
                }
            }
            // 2.3 如果批发商是"BBAC"
            if ("MBCL".equals(e.get批发商())) {
                //如果预计到港日期或者实际到港日期大于等于本月20号,更改nbi车辆状态为“非本月待批发”
                if (e.get预计到港日期() == null || e.get实际到港日期() == null) {
                    e.setNbi车辆状态("非本月待批发");
                    continue;
                }
                if (DateFormatUtils.getFormatDate("yyyy-MM-dd", e.get预计到港日期()).getTime() >= strTwintyDay.getTime() ||
                        DateFormatUtils.getFormatDate("yyyy-MM-dd", e.get实际到港日期()).getTime() >= strTwintyDay.getTime()) {
                    e.setNbi车辆状态("非本月待批发");
                } else {
                    e.setNbi车辆状态("本月待批发");
                }
            } else {
                //2.4 如果批发商不是"BBAC"
                //如果预计下线日期大于等于本月倒数第三天，更改nbi车辆状态为“非本月待批发”
                if (e.get预计下线日期() != null) {
                    if (DateFormatUtils.getFormatDate("yyyy-MM-dd", e.get预计下线日期()).getTime() >= strLastThree.getTime()) {
                        e.setNbi车辆状态("非本月待批发");
                    } else {
                        e.setNbi车辆状态("本月待批发");
                    }
                } else {
                    e.setNbi车辆状态("非本月待批发");
                }
            }
        }
        lsh库存表Repository.save(list);
        return true;
    }

    @Override
    public List getCarTransferCustInfo(String dlr, String prodCode) {
        logger.info("getCarTransferCustInfo传入参数为:" + dlr + "," + prodCode);
        List list = repository.getCarTransferCustInfo(dlr, prodCode);
        // 界面按钮初始化变量
        if (list != null && list.size() != 0) { // 有返回数据时
            Map<String, Object> moMap = (Map) list.get(0);
            String isEmergency = (moMap).get("is_emegency") + ""; // 是否紧急
            String outConfirm_user = (String) (moMap).get("out_confirm_user"); // 调出操作人
            String fundInUser = (String) (moMap).get("fund_in_user"); // 收款人
            String stockOutUser = (String) (moMap).get("stock_out_user"); // 出库操作人
            String stockInUser = (String) (moMap).get("stock_in_user"); // 入库操作人
            // 出库按钮，紧急调车时，审批完成可以出库，非紧急时，收款完成才能出库
            if (("0".equals(isEmergency) && outConfirm_user != null) //
                    || ("1".equals(isEmergency) && fundInUser != null)) {
                moMap.put("canTransferOut", "1");
            } else {
                moMap.put("canTransferOut", "0");
            }
            // 入库按钮，出库后，且未入库时，点亮
            if (("0".equals(isEmergency) && stockOutUser != null && stockInUser == null)
                    || ("1".equals(isEmergency) && stockOutUser != null && stockInUser == null)) {
                moMap.put("canTransferIn", "1");
            } else {
                moMap.put("canTransferIn", "0");
            }
            Lsh库存表Model stockMo = lsh库存表Repository.findLshRecordByProId(prodCode);
            if (stockMo == null) {
                return new ArrayList();
            } else {
                String isTransferComplete = carTransferService.isTransferComplete(stockMo);
                if ("00".equals(isTransferComplete)) { // 如果调车流程完成，不显示历史
                    moMap.put("showHistory", "0");
                } else { // 未完成才显示历史
                    moMap.put("showHistory", "1");
                }
            }
        } // 无数据时不处理
        return list;
    }

//    @Override
//    public boolean updateOuterStatus(UpdateOuterStatusReq req) {
//        //入库，入库日期赋为当前时间
//        Date dt = DateFormatUtils.getFormatDate("yyyy-MM-dd", new Date());
//        int a = lsh库存表Repository.updateOuterStatus(Integer.valueOf(req.productNo), req.guest, req.reason,
//                req.amount, req.innerDealer, req.outerDealer, req.outerStatus, dt);
//        return a > 0 ? true : false;
//    }

    @Override
    public ResultData updateOuterStatusRuku(String dealer, String username, UpdateOuterStatusReq req) {
        logger.info("updateOuterStatusRuku参数为:dealer=" + dealer + ",username=" + username + ",req=" + JsonObjectUtils.writeAsJson(req));
        String errMsg = "入库异常";
        try {
            // 入库的条件，调车物流状态 = 调出出库，并且调入经销商 = 当前经销商
            Lsh库存表Model stockMo = lsh库存表Repository.findOne(Integer.parseInt(req.productNo));
            // 车辆属于本店，或调车物流状态不是 调出出库，修改失败
            if (!stockMo.get调入经销商().equals(dealer) || !"调出出库".equals(stockMo.get调车物流状态())) {
                return new ResultData("false", "车辆不属于本店，或尚未出库", null);
            }
            // 入库，入库日期赋为当前时间
            Date dt = DateFormatUtils.getFormatDate("yyyy-MM-dd", new Date());
            int a = lsh库存表Repository.updateOuterStatusRuku(Integer.valueOf(req.productNo), req.guest, req.reason,
                    req.amount, req.outerStatus, dt);
            // 同步修改car_transfer_log
            List<CarTransferLogModel> transMoList = carTransferLogRepository.findByStockId(Integer.parseInt(req.productNo));
            CarTransferLogModel transMo = transMoList.get(0);
            transMo.setLogisticsStatus("调入入库");
            transMo.setStockInDate(java.sql.Date.valueOf(LocalDate.now()));
            transMo.setStockInUser(username);
            transMo.setModifyDate(Timestamp.valueOf(LocalDateTime.now()));
            return new ResultData("true", null, null);
        } catch (Exception e) {
            logger.error(errMsg, e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ResultData("false", errMsg, null);
        }
    }


//    @Override
//    @Transactional
//    public CarTransferLogModel saveByStockCode(CarTransferLogModel model) {
//        CarTransferLogModel c = null;
//        CarTransferLogModel cc = null;
//        try {
//            if (model.getId() == null || "".equals(model.getId())) {
//                c = new CarTransferLogModel();
//            } else {
//                c = carTransferLogRepository.findOne(model.getId());
//            }
//            c.setCustomName(model.getCustomName());
//            c.setCustomTel(model.getCustomTel());
//            c.setExpectedLateInStockDate(model.getExpectedLateInStockDate());
//            c.setExpectedLateMoneyInAccount(model.getExpectedLateMoneyInAccount());
//            c.setExpectedCustomPurchasing(model.getExpectedCustomPurchasing());
//            c.setInternalApplyDate(model.getInternalApplyDate());
//            c.setInternalApplyUser(model.getInternalApplyUser());
//            c.setStockCode(model.getStockCode());
//            c.setIsEmegency(model.getIsEmegency());
//            c.setCompareStockCode(model.getCompareStockCode());
//            c.setModifyDate(DateFormatUtils.getFormatTimestamp("yyyy-MM-dd HH:mm:ss", new Date()));
//            cc = carTransferLogRepository.save(model);
//
//            Lsh库存表Model store = lsh库存表Repository.findOne(cc.getStockCode());
//
//            //同时更改车辆的内部可见为不可见
//            Lsh库存内部可见Model model内部 = lsh库存内部可见Repository.findBystocknumber(store.get库存编号());
//            if (model内部 == null) {
//                //新增一条
//                Lsh库存内部可见Model newM = new Lsh库存内部可见Model();
//                newM.set内部可见角色("SC/CDO不可见");
//                newM.set库存编号(store.get库存编号());
//                newM.set更新时间(DateFormatUtils.getFormatTimestamp("yyyy-MM-dd HH:mm:ss", new Date()));
//                newM.set更新账号("Admin");
//                lsh库存内部可见Repository.save(newM);
//            } else {
//                //修改为“SC/CDO不可见”
//                lsh库存内部可见Repository.updateStatusById("SC/CDO不可见", model内部.get库存内部可见编号());
//            }
//        } catch (Exception e) {
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//            logger.error("系统异常。", e);
//        }
//        return cc;
//    }

    @Override
    public List getInnerDetails(String productNo) {
        return repository.getInnerDetails(productNo);
    }

    @Override
    public List selectExpectGiveCarDateAndReason(String vin) {
        return repository.selectExpectGiveCarDateAndReason(vin);
    }

    @Override
    public List getInnerData(String param, String type) {
        return repository.getInnerData(param, type);
    }

    @Override
    public List getOuterVisableLevel(String productNo) {
        return repository.getOuterVisableLevel(productNo);
    }

    @Override
    public List getInnerVisableRole(String productNo) {
        return repository.getInnerVisableRole(productNo);
    }

    @Override
    @Transactional
    public boolean updateOuterVisableLevel(UpOuterVisableLevelRequest upVisableReq) {
        String[] pNo = upVisableReq.productNo.split(",");
        for (String productNo : pNo) {

            try {
                lsh库存表Repository.updateOuterVisableLevel(upVisableReq.visableLevel, productNo);
            } catch (Exception e) {
                logger.error("数据更新异常。", e);
                TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
                return false;
            }
        }

        return true;
    }

    public List getKCNumByProductNum(String productNo) {
        return repository.getKCNumByProductNum(productNo);
    }

    @Override
    public boolean delInternalVisibleLevel(DelInternalVisibleLevelRequest request) {
        boolean flag;
        try {
            lsh库存内部可见Repository.delInternalVisibleLevel(request.库存编号);
            flag = true;
        } catch (Exception e) {
            logger.error("数据删除异常。", e);
            flag = false;
        }
        return flag;
    }

    @Override
    @Transactional
    public boolean saveInternalVisibleLevel(SaveInternalVisibleLevelRequest saveRequest, String username) {
        Timestamp nowtime = new Timestamp(new Date().getTime());
        String[] pNo = saveRequest.productNo.split(",");
        String visableLevel = saveRequest.visableLevel;
        for (String productNo : pNo) {
            try {
                Lsh库存表Model lsh库存表Model = lsh库存表Repository.findLshRecordByProId(productNo);//获取生产号为  productNo的 对象
                Integer id = lsh库存表Model.get库存编号();
                Lsh库存内部可见Model lsh库存内部可见Model = lsh库存内部可见Repository.findBystocknumber(id);//获取库存编号为  的lsh库存内部可见对象
                if ((visableLevel == null || visableLevel.equals("")) && lsh库存内部可见Model != null) {
                    lsh库存内部可见Repository.delInternalVisibleLevel(id);
                } else {
                    if (lsh库存内部可见Model != null) {
                        lsh库存内部可见Model.set内部可见角色(visableLevel);
                        lsh库存内部可见Model.set更新时间(nowtime);
                        lsh库存内部可见Model.set更新账号(username);
                        lsh库存内部可见Repository.save(lsh库存内部可见Model);

                    } else {
                        Lsh库存内部可见Model newlsh库存内部可见Model = new Lsh库存内部可见Model();
                        newlsh库存内部可见Model.set库存编号(id);
                        newlsh库存内部可见Model.set内部可见角色(visableLevel);
                        newlsh库存内部可见Model.set更新时间(nowtime);
                        newlsh库存内部可见Model.set更新账号(username);
                        lsh库存内部可见Repository.save(newlsh库存内部可见Model);
                    }
                }

            } catch (Exception e) {
                logger.error("数据保存异常。", e);
                TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
                return false;
            }
        }


     /*   boolean flag;
        try {
            lsh库存内部可见Repository.save(model);
            flag = true;
        } catch (Exception e) {
            Logger.getLogger(SalesServiceImpl.class).error(e);
            flag = false;
        }
        return flag;*/
        return true;
    }


    public List getSelfCarStatusList(String permit) {

        return this.repository.getSelfCarStatusList(permit);

    }

    @Override
    public List followCluesList(String permit, String date) {
        List list = this.repository.followCluesList(permit, date);
        for (int i = 0; i < list.size(); i++) {
            Map map = (Map) list.get(i);
            String phone = (String) map.get("电话号码");
            if (11 == phone.length()) {
                phone = phone.substring(0, 3) + "****" + phone.substring(7, phone.length());
                map.put("电话号码", phone);
            }
        }
        return list;
    }

    @Override
    /*功能描述，周报表数据拼接 */
    public List getWeekReprot(String years, String permit) {
        String[] years1 = years.split(",");
        //  List requestList = Lists.newArrayList();
        List carTypeList = weekReprotRepository.getCarType(permit);
        for (int i = 0; i < carTypeList.size(); i++) {
            Map result = (Map) carTypeList.get(i);
            String carTypeId = result.get("id").toString();//获取车型编号
            StringBuffer carIno = new StringBuffer(result.get("Segments").toString());
            carIno.append(result.get("Baumuster").toString());
            carIno.append(result.get("Chassis").toString());
            carIno.append(result.get("Model Short").toString());
            result.put("carIno", carIno.toString());
            /**********订单数据***********/
            /*获取周订单*/
            result.putAll((Map) weekReprotRepository.getWeekOrders(permit, carTypeId).get(0));
            /*获取周订单*/
            result.putAll((Map) weekReprotRepository.getMonthOrders(permit, carTypeId).get(0));
            /*获取年订单*/
            result.putAll((Map) weekReprotRepository.getYearOrders(permit, carTypeId).get(0));
            /*获未开票订单订单取*/
            result.putAll((Map) weekReprotRepository.getNoInvOrders(permit, carTypeId).get(0));
            /**********零售数据***********/
            /* 本周零售数据*/
            result.putAll((Map) weekReprotRepository.getWeekSales(permit, carTypeId).get(0));
            /*本月零售数据*/
            result.putAll((Map) weekReprotRepository.getMonthSales(permit, carTypeId).get(0));
            /*本年零售数据*/
            result.putAll((Map) weekReprotRepository.getYearSales(permit, carTypeId).get(0));
            /**********库存数据***********/
            /* 有订单的库存数据*/
            result.putAll((Map) weekReprotRepository.getOrderStock(permit, carTypeId).get(0));
            /*无订单的库存数据*/
            result.putAll((Map) weekReprotRepository.getNoOrderStock(permit, carTypeId).get(0));
            /*交车未开票库存数据*/
            result.putAll((Map) weekReprotRepository.getNoInvStock(permit, carTypeId).get(0));
            /**********每月生产未销售数据***********/
            for (String year : years1) {
                for (int j = 1; j < 13; j++) {
                    result.putAll((Map) weekReprotRepository.getNoSaleCars(permit, carTypeId, year, j + "").get(0));
                }

            }
        }

        return carTypeList;
    }

    public List getRoleAndpermitAndname(SaveInternalVisibleLevelRequest reli) {
        List<List> nima = new ArrayList();
        List nimason = null;
        if (reli != null) {
            String nisonsm = reli.productNo;
            String[] nimade = nisonsm.split(",");
            if (nimade != null) {
                for (int i = 0; i < nimade.length; i++) {
                    String sheng = nimade[i];
                    nimason = this.repository.getRoleAndpermitAndname(sheng);
                    nima.add(nimason);
                }
            }
        }
        return nima;
    }

    @Override
    public ResultData isShunt(IsShuntReq req, String permit) {
        ResultData rd = new ResultData("false", null, null);
        try {
            if (req != null) {
                if (req.otherShopPermit == null || "".equals(req.otherShopPermit)) {
                    rd.setMessage("请选择调出经销商");
                    return rd;
                }
                //获取调车调入审批设置,校验是否设置审批人
                PushApprovalItemSettingModel p1 = pushApprovalItemSettingRepository.getModelByPermitAndType(permit, 8);
                if (p1 == null) {
                    rd.setMessage("请设置调入审批人后再执行调入申请操作");
                    return rd;
                }
                //获取调车调出审批设置,校验是否设置审批人
                PushApprovalItemSettingModel p2 = pushApprovalItemSettingRepository.getModelByPermitAndType(req.otherShopPermit, 9);
                if (p2 == null) {
                    rd.setMessage("请设置调出审批人后再执行调入申请操作");
                    return rd;
                }

                Lsh库存表Model store = lsh库存表Repository.findLshRecordByVin(req.vin);
                if (store != null) {
                    String status = store.get调车物流状态();
                    if ("调入申请".equals(status) || "调入申请确认".equals(status) || "调入入库".equals(status) ||
                            "调出申请确认".equals(status)) {
                        rd.setResult("false");
                        rd.setMessage("该车辆正在调车流程中");
                        return rd;
                    } else {
                        rd.setResult("true");
                        rd.setMessage("该车辆可以被调");
                        return rd;
                    }
                } else {
                    logger.warn("没有此车架号的库存信息");
                    rd.setResult("false");
                    rd.setMessage("没有此车架号的库存信息");
                    return rd;
                }
            }
        } catch (Exception e) {
            logger.error("判断车辆是否可以被调程序异常", e);
        }
        return rd;
    }
//    @Override
//    public ResultData isShunt(IsShuntReq req) {
//        ResultData rd = new ResultData();
//        Lsh库存表Model store = lsh库存表Repository.findLshRecordByVin(req.vin);
//        if (store != null) {
//            String status = store.get调车物流状态();
//            if ("调入申请".equals(status) || "调入申请确认".equals(status) || "调入入库".equals(status) ||
//                    "调出申请确认".equals(status)) {
//                rd.setResult("false");
//                rd.setMessage("该车辆正在调车流程中");
//                return rd;
//            } else {
//                rd.setResult("true");
//                rd.setMessage("该车辆可以被调");
//                return rd;
//            }
//        } else {
//            logger.warn("没有此车架号的库存信息");
//            rd.setResult("false");
//            rd.setMessage("没有此车架号的库存信息");
//            return rd;
//        }
//    }

   /* public ResultData saveCarStates(List<IsShuntReq> req) {
        ResultData rd = new ResultData();
        String msg = "";
        String flag = "false";
        List failList = new ArrayList();
        try {
            Lsh库存表Model store = new Lsh库存表Model();
            for (int i = 0; i < req.size(); i++) {
                IsShuntReq item = req.get(i);
                //修改原因：前台传参数是 车架号，不能当成 库存编号 用 --2017-09-15
                //int id = Integer.parseInt(item.vin);
                store = lsh库存表Repository.findLshRecordByVin(item.vin);
                if ("已卖".equals(store.get车辆零售状态())) {
                    store.setCarState("01");
                } else {
                    failList.add(store);
                }
                lsh库存表Repository.save(store);
            }
            msg = "更改车辆归档状态成功";
            flag = "true";
        } catch (Exception e) {
            logger.error("更改车辆归档状态失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            msg = "更改车辆归档状态失败";
            flag = "false";
        }
        rd.setMessage(msg);
        rd.setResult(flag);
        rd.setPageData(new PageData(failList, failList.size()));
        return rd;
    }*/

    /**
     * 优化后的归档
     * @param req
     * @return
     */
    public ResultData saveCarStates(List<IsShuntReq> req) {
        List<String> failList = new ArrayList<String>();
        List<String> sussList = new ArrayList<String>();
        try {
            for (int i = 0; i < req.size(); i++) {
                IsShuntReq item = req.get(i);
                List<报价交车表Model> leaveCarList = i报价交车表Repository.hasLeaveCarByVin(item.vin);
                Lsh库存表Model store =  lsh库存表Repository.findLshRecordByVin(item.vin);
                if (null != leaveCarList || leaveCarList.size() > 0) {
                    store.setCarState("01");
                    sussList.add(item.vin);
                    lsh库存表Repository.updateStockStatus(item.vin,"01");
                } else {
                    failList.add(item.vin);
                }
            }
        } catch (Exception e) {
            logger.error("更改车辆归档状态异常", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return new ResultData("true", "成功归档车辆：" +sussList.toString() +"|" + "未交车不能归档车辆："  +  failList.toString());
    }

    public ResultData findDealerInfoById(String quoteId) {
        ResultData rd = new ResultData();
        String msg = "";
        String flag = "false";
        List failList = new ArrayList();
        try {
            failList = repository.findDealerInfoById(quoteId);

            flag = "true";
        } catch (Exception e) {
            logger.error("行政详情获取失败", e);
            msg = "获取失败";
            flag = "false";
        }
        rd.setMessage(msg);
        rd.setResult(flag);
        rd.setPageData(new PageData(failList, failList.size()));
        return rd;
    }

    public ResultData getTransferCarList(String permit) {
        return null;
    }

    @Transactional
    public ResultData getDealerBatchInfo(GetSaleListRequests re, String p, String s) {
        ResultData rd = new ResultData();
        String msg = "查询成功";
        String flag = "true";
        PageData failList = new PageData();
        try {
            failList = repository.getDealerBatchInfo(re, p, s);
        } catch (Exception e) {
            logger.info("查询经销商数据出错");
            flag = "false";
            msg = "查询出错";
        }
        rd.setMessage(msg);
        rd.setResult(flag);
        rd.setPageData(failList);
        return rd;
    }

    @Transactional
    public ResultData saveDealerInfoItem(List<saveDealerInfoItem> modellist, String permit, String username) {
        ResultData rd = new ResultData();
        String msg = "";
        String flag = "false";
        PageData failList = new PageData();
        for (int i = 0; i < modellist.size(); i++) {
            saveDealerInfoItem item = modellist.get(i);
            if(Strings.isNullOrEmpty(item.大区)){
                item.大区 = groupAreaRepository.getParentName(item.经销商全称en);
            }

            // 维护 lsh区域表，
            onlyupdateAreaInfo(item.大区, item.小区);

            Lsh经销商表Model modelitem = lsh经销商表Repository.findOne(item.bmbs);

            if (modelitem != null) {
                flag = onlyUpdateSalesDealerInfo(modelitem, item, permit, username);
            } else {
                flag = onlyInsertSalesDealerInfo(item, permit, username);
                systemService.initPermitData(item.bmbs);
            }
        }
        rd.setMessage(msg);
        rd.setResult(flag);
        rd.setPageData(failList);
        return rd;
    }

    @Transactional
    private String onlyInsertSalesDealerInfo(saveDealerInfoItem newitem, String permit, String username) {
        String flag = "";
        Lsh经销商表Model oldmodelitem = new Lsh经销商表Model();
        try {
            if (!Strings.isNullOrEmpty(newitem.bmbs)) {
                oldmodelitem.setBmbs(newitem.bmbs);
            }

            if (!Strings.isNullOrEmpty(newitem.lsh)) {
                oldmodelitem.setLsh(newitem.lsh);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商名)) {
                oldmodelitem.set经销商名(newitem.经销商名);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商名en)) {
                oldmodelitem.set经销商名en(newitem.经销商名en);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商)) {
                oldmodelitem.set经销商(newitem.经销商);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商en)) {
                oldmodelitem.set经销商en(newitem.经销商en);
            }
            if (!Strings.isNullOrEmpty(newitem.省份)) {
                oldmodelitem.set省份(newitem.省份);
            }
            if (!Strings.isNullOrEmpty(newitem.省份en)) {
                oldmodelitem.set省份en(newitem.省份en);
            }
            if (!Strings.isNullOrEmpty(newitem.城市)) {
                oldmodelitem.set城市(newitem.城市);
            }
            if (!Strings.isNullOrEmpty(newitem.城市en)) {
                oldmodelitem.set城市en(newitem.城市en);
            }
            if (!Strings.isNullOrEmpty(newitem.大区)) {
                oldmodelitem.set大区(newitem.大区);
            }
            if (!Strings.isNullOrEmpty(newitem.大区en)) {
                oldmodelitem.set大区en(newitem.大区en);
            }
            if (!Strings.isNullOrEmpty(newitem.小区)) {
                oldmodelitem.set小区(newitem.小区);
            }
            if (!Strings.isNullOrEmpty(newitem.小区en)) {
                oldmodelitem.set小区en(newitem.小区en);
            }
            if (!Strings.isNullOrEmpty(newitem.cta)) {
                oldmodelitem.setCta(newitem.cta);
            }
            if (!Strings.isNullOrEmpty(newitem.ctaEn)) {
                oldmodelitem.setCtaEn(newitem.ctaEn);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商全称)) {
                oldmodelitem.set经销商全称(newitem.经销商全称);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商全称en)) {
                oldmodelitem.set经销商全称en(newitem.经销商全称en);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商地址)) {
                oldmodelitem.set经销商地址(newitem.经销商地址);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商地址en)) {
                oldmodelitem.set经销商地址en(newitem.经销商地址en);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商电话)) {
                oldmodelitem.set经销商电话(newitem.经销商电话);
            }
            // 特别 处理
            if (!Strings.isNullOrEmpty(newitem.经销商状态)) {
                if (newitem.经销商状态.equals("Closed")) {
                    oldmodelitem.set经销商状态("已关闭");
                }

            }

            if (!Strings.isNullOrEmpty(newitem.经销商类型)) {
                oldmodelitem.set经销商类型(newitem.经销商类型);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商功能)) {
                oldmodelitem.set经销商功能(newitem.经销商功能);
            }
            if (!Strings.isNullOrEmpty(newitem.功能类型)) {
                oldmodelitem.set功能类型(newitem.功能类型);
            }
            if (!Strings.isNullOrEmpty(newitem.销售能力)) {
                oldmodelitem.set销售能力(newitem.销售能力);
            }

            if (!Strings.isNullOrEmpty(newitem.ncCode)) {
                oldmodelitem.setNcCode(newitem.ncCode);
            }
            if (!Strings.isNullOrEmpty(newitem.dmsCode)) {
                oldmodelitem.setDmsCode(newitem.dmsCode);
            }
            if (!Strings.isNullOrEmpty(newitem.salesCode)) {
                oldmodelitem.setSalesCode(newitem.salesCode);
            }
            if (!Strings.isNullOrEmpty(newitem.dealerCode)) {
                oldmodelitem.setDealerCode(newitem.dealerCode);
            }
            if (!Strings.isNullOrEmpty(newitem.imsCode)) {
                oldmodelitem.setImsCode(newitem.imsCode);
            }
            if (!Strings.isNullOrEmpty(newitem.是否测试)) {
                oldmodelitem.set是否测试(newitem.是否测试);
            }
            if (!Strings.isNullOrEmpty(newitem.更新账号)) {
                oldmodelitem.set更新账号(newitem.更新账号);
            }
            Timestamp nowupdatetime = new Timestamp(System.currentTimeMillis());
            if (!Strings.isNullOrEmpty(newitem.更新时间)) {
                oldmodelitem.set更新时间(nowupdatetime);
            }
            SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");


            if (!Strings.isNullOrEmpty(newitem.开业日期)) {
                Date date2 = formatter2.parse(newitem.开业日期);
                oldmodelitem.set开业日期(date2);
            }
            if (!Strings.isNullOrEmpty(newitem.生效日期)) {
                Date date3 = formatter2.parse(newitem.生效日期);
                oldmodelitem.set生效日期(date3);
            }
            if (!Strings.isNullOrEmpty(newitem.projectCode)) {
                oldmodelitem.setProjectCode(newitem.projectCode);
            }
            lsh经销商表Repository.save(oldmodelitem);
            flag = "true";

        } catch (Exception e) {
            logger.info(String.format("插入经销商数据出错。从Excel导入的 bmbs=%s,", newitem.bmbs));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return flag;
    }

    private void onlyupdateAreaInfo(String bigarea, String smartarea) {
        if (!Strings.isNullOrEmpty(bigarea) && !Strings.isNullOrEmpty(smartarea)) {
            Lsh区域ModelPK pks = new Lsh区域ModelPK();
            pks.set大区(bigarea);
            pks.set小区(smartarea);
            Lsh区域Model model = lsh区域Repository.findOne(pks);
            if (model == null) {
                Lsh区域Model newmodel = new Lsh区域Model();
                newmodel.set小区(smartarea);
                newmodel.set大区(bigarea);
                lsh区域Repository.save(newmodel);
            }
        }


    }

    private String onlyUpdateSalesDealerInfo(Lsh经销商表Model oldmodelitem, saveDealerInfoItem newitem, String permit, String username) {
        String flag = "false";
        try {


            if (!Strings.isNullOrEmpty(newitem.lsh)) {
                oldmodelitem.setLsh(newitem.lsh);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商名)) {
                oldmodelitem.set经销商名(newitem.经销商名);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商名en)) {
                oldmodelitem.set经销商名en(newitem.经销商名en);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商)) {
                oldmodelitem.set经销商(newitem.经销商);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商en)) {
                oldmodelitem.set经销商en(newitem.经销商en);
            }
            if (!Strings.isNullOrEmpty(newitem.省份)) {
                oldmodelitem.set省份(newitem.省份);
            }
            if (!Strings.isNullOrEmpty(newitem.省份en)) {
                oldmodelitem.set省份en(newitem.省份en);
            }
            if (!Strings.isNullOrEmpty(newitem.城市)) {
                oldmodelitem.set城市(newitem.城市);
            }
            if (!Strings.isNullOrEmpty(newitem.城市en)) {
                oldmodelitem.set城市en(newitem.城市en);
            }
            if (!Strings.isNullOrEmpty(newitem.大区)) {
                oldmodelitem.set大区(newitem.大区);
            }
            if (!Strings.isNullOrEmpty(newitem.大区en)) {
                oldmodelitem.set大区en(newitem.大区en);
            }
            if (!Strings.isNullOrEmpty(newitem.小区)) {
                oldmodelitem.set小区(newitem.小区);
            }
            if (!Strings.isNullOrEmpty(newitem.小区en)) {
                oldmodelitem.set小区en(newitem.小区en);
            }
            if (!Strings.isNullOrEmpty(newitem.cta)) {
                oldmodelitem.setCta(newitem.cta);
            }
            if (!Strings.isNullOrEmpty(newitem.ctaEn)) {
                oldmodelitem.setCtaEn(newitem.ctaEn);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商全称)) {
                oldmodelitem.set经销商全称(newitem.经销商全称);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商全称en)) {
                oldmodelitem.set经销商全称en(newitem.经销商全称en);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商地址)) {
                oldmodelitem.set经销商地址(newitem.经销商地址);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商地址en)) {
                oldmodelitem.set经销商地址en(newitem.经销商地址en);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商电话)) {
                oldmodelitem.set经销商电话(newitem.经销商电话);
            }
            // 特别 处理
            if (!Strings.isNullOrEmpty(newitem.经销商状态)) {
                if (newitem.经销商状态.equals("Closed")) {
                    oldmodelitem.set经销商状态("已关闭");
                }

            }

            if (!Strings.isNullOrEmpty(newitem.经销商类型)) {
                oldmodelitem.set经销商类型(newitem.经销商类型);
            }
            if (!Strings.isNullOrEmpty(newitem.经销商功能)) {
                oldmodelitem.set经销商功能(newitem.经销商功能);
            }
            if (!Strings.isNullOrEmpty(newitem.功能类型)) {
                oldmodelitem.set功能类型(newitem.功能类型);
            }
            if (!Strings.isNullOrEmpty(newitem.销售能力)) {
                oldmodelitem.set销售能力(newitem.销售能力);
            }

            if (!Strings.isNullOrEmpty(newitem.ncCode)) {
                oldmodelitem.setNcCode(newitem.ncCode);
            }
            if (!Strings.isNullOrEmpty(newitem.dmsCode)) {
                oldmodelitem.setDmsCode(newitem.dmsCode);
            }
            if (!Strings.isNullOrEmpty(newitem.salesCode)) {
                oldmodelitem.setSalesCode(newitem.salesCode);
            }
            if (!Strings.isNullOrEmpty(newitem.dealerCode)) {
                oldmodelitem.setDealerCode(newitem.dealerCode);
            }
            if (!Strings.isNullOrEmpty(newitem.imsCode)) {
                oldmodelitem.setImsCode(newitem.imsCode);
            }
            if (!Strings.isNullOrEmpty(newitem.是否测试)) {
                oldmodelitem.set是否测试(newitem.是否测试);
            }
            if (!Strings.isNullOrEmpty(newitem.更新账号)) {
                oldmodelitem.set更新账号(newitem.更新账号);
            }
            Timestamp nowupdatetime = new Timestamp(System.currentTimeMillis());
            if (!Strings.isNullOrEmpty(newitem.更新时间)) {
                oldmodelitem.set更新时间(nowupdatetime);
            }
            SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");


            if (!Strings.isNullOrEmpty(newitem.开业日期)) {
                Date date2 = formatter2.parse(newitem.开业日期);
                oldmodelitem.set开业日期(date2);
            }
            if (!Strings.isNullOrEmpty(newitem.生效日期)) {
                Date date3 = formatter2.parse(newitem.生效日期);
                oldmodelitem.set生效日期(date3);
            }
            if (!Strings.isNullOrEmpty(newitem.projectCode)) {
                oldmodelitem.setProjectCode(newitem.projectCode);
            }
            lsh经销商表Repository.save(oldmodelitem);
            flag = "true";

        } catch (Exception e) {
            logger.info(String.format("更新经销商数据出错。从Excel导入的 bmbs=%s,", newitem.bmbs));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return flag;
    }


    public ResultData getCompanyAndCTA(GetSaleListRequests re, String p, String s) {
        ResultData rd = new ResultData();
        PageData pg = new PageData();
        String flag = "true";
        String msg = "";
        List rslist = new ArrayList();

        List modellist = repository.findPermitAndAh();
        List Ctalist = repository.getAllCTAlists();
        List falsebigArea = repository.getAllBigArealists();
        List bigArea = new ArrayList();

        for (int i = 0; i < falsebigArea.size(); i++) {
            Map resultMap = new HashMap();
            Map remap = (Map) falsebigArea.get(i);
            resultMap.put("大区", remap.get("大区"));
            resultMap.put("大区_EN", remap.get("大区_EN"));
            String daqu = remap.get("大区").toString();
            List smalllist = repository.getAllSmallArealists(daqu);
            resultMap.put("下属的小区详细", smalllist);

            bigArea.add(resultMap);
        }

        Map remap = new HashMap();
        remap.put("总公司", modellist);
        remap.put("CTA", Ctalist);
        remap.put("大区", bigArea);

        rslist.add(remap);

        pg.setData(rslist);
        rd.setPageData(pg);
        rd.setResult(flag);
        rd.setMessage(msg);
        return rd;

    }

    @Override
    public ResultData getExchangeList(ExchangeInfo requestBase, String permit) {
        ResultData resultData = new ResultData("false", null, null);
        try {
            resultData.setPageData(repository.getExchangeList(requestBase, permit));
            resultData.setResult("true");
            resultData.setMessage("成功");

        } catch (Exception e) {
            resultData.setMessage("获取失败");
            logger.error("换车列表", e);
        }
        return resultData;
    }

    @Override
    public ResultData getChangeCarList(ChangeCarInfo info, String permit) {
        ResultData resultData = new ResultData("false", null, null);
        try {
            // 设置来源
            Lsh库存表Model stockModel = lsh库存表Repository.selectByVin(info.vin);
            Lsh车型Model carModel = lsh车型Repository.findOne(stockModel.get车型编号());
            info.source = carModel.get来源();
            resultData.setPageData(repository.getChangeCarList(info, permit));
            resultData.setResult("true");
            resultData.setMessage("成功");

        } catch (Exception e) {
            System.out.print(e);
            resultData.setMessage("获取失败");
            logger.error("换车列表", e);
        }
        return resultData;
    }

    @Override
    @Transactional
    public ResultData administrativeChangeCar(ChangeCar info, String userName, String permit) {
        ResultData resultData = new ResultData("false", null, null);
        try {
            //1.查出该条报价单信息
            报价单表Model bjModel = i报价单表Repository.findBy报价编号(info.quoId);
            if (StringUtils.isNullOrBlank(bjModel.get库存编号())) {
                throw new AppException("换车失败!请确认该条订单是否挂车！");
            }

            if (StringUtils.isNullOrBlank(info.stockNumber)) {
                throw new AppException("换车失败!请确认该所选车辆是否存在，刷新后重试！");
            }

            //2.查出 两条车的库存信息
            Lsh库存表Model oldCarInfo = lsh库存表Repository.findOne(bjModel.get库存编号());
            Lsh库存表Model newCarInfo = lsh库存表Repository.findOne(info.stockNumber);
            //3.更换报价单表中的  车辆信息
            bjModel.set库存编号(newCarInfo.get库存编号());
            bjModel.set车型编号(newCarInfo.get车型编号());
            bjModel.set外观(newCarInfo.get颜色());
            bjModel.set内饰(newCarInfo.get内饰());
            i报价单表Repository.save(bjModel);
            //4.清除旧车的挂车信息,添加新车数据
            oldCarInfo.set报价编号(null);
            oldCarInfo.set车辆零售状态("未卖");
            lsh库存表Repository.save(oldCarInfo);
            newCarInfo.set报价编号(info.quoId);
            newCarInfo.set车辆零售状态("已卖");
            lsh库存表Repository.save(newCarInfo);

            //5.做日志
            ExchangeStockLogModel logModel = new ExchangeStockLogModel();
            logModel.setNewStockId(newCarInfo.get库存编号());
            logModel.setOldStockId(oldCarInfo.get库存编号());
            logModel.setOrgQid(bjModel.get初始报价单号());
            logModel.setQuoteId(bjModel.get报价编号());
            logModel.setUpdateAccount(userName);
            logModel.setUpdateTime(new Timestamp(new Date().getTime()));
            exchangeStockLogRepository.save(logModel);

                String call;
                String salesCode  = info.salesName;
                String phone = info.telNumber;
                String sex =  顾客记录汇总repository.findCusByCustomerIDAndPhone(salesCode,phone);
                if("男".equals(sex)){
                    call="先生";
                }else if ("女".equals(sex)){
                    call="女士";
                }else {
                    call="先生/女士";
                }

            //6.发送消息
            String news = "客户:" + info.cusName + call+"，电话号码:" + info.telNumber +
                    "所属销售顾问" + info.salesName + "账号" + info.salesCode + "，已由销售行政" + userName + "换车" +
                    "，旧车车架号为：" + oldCarInfo.get车架号() + "，新车车架号为：" + newCarInfo.get车架号() + "，请注意查看。";
            //极光推送
            JsonObject json = JsonObjectUtils.getJsonObject("订单", null, null, info.salesTel, null, info.salesCode);
            List sendName = Lists.newArrayList();
            sendName.add(info.salesCode);
            JPush.SendPushITaskForAndroidAndIos(news, news, json, sendName);
            //存入lsh数据库
            LshMsgUtils.getLshMsg(permit, userName, permit, info.salesCode, "订单", news,
                    userName, info.telNumber);
            resultData.setResult("true");
            resultData.setMessage("换车成功");

        } catch (AppException e) {
            TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
            resultData.setMessage(e.getMessage());
            resultData.setResult("false");
        } catch (Exception e) {
            System.out.print(e);
            TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
            resultData.setMessage("换车失败");
            logger.error("换车列表", e);
        }
        return resultData;
    }

    public Map getCodeByRole(ChangeCar info, String userName, String permit) {
        Map ma = new HashMap();
        List<Lsh经销商表Model> modellsit = lsh经销商表Repository.findAllPermitBy本店(info.cusName);
        if (modellsit != null && modellsit.size() > 0) {
            Lsh经销商表Model modelitem = modellsit.get(0);
            String resultStr = modelitem.getBmbs();
            String cta = modelitem.getCta();
            String daqu = modelitem.get大区();
            if (Strings.isNullOrEmpty(cta)) {
                ma.put("cta", "其他cta");
            } else {
                ma.put("cta", cta);
            }
            ma.put("code", resultStr);
            ma.put("bigArea", daqu);
            ma.put("role", info.cusName);
            return ma;
        }
        return ma;
    }

    // 传入的 是大区
    public Map getCtaCodeByRole(ChangeCar info, String userName, String permit) {
        Map ma = new HashMap();
        List<String> modellsit = lsh经销商表Repository.findPermitAndAhBigArea(info.cusName);
        ma.put("cta", modellsit);
        return ma;
    }

    // 传入的 是cta
    public Map getBMBsCodeByRole(ChangeCar info, String userName, String permit) {
        Map ma = new HashMap();
        Map mas = new HashMap();
        List<Lsh经销商表Model> modellsit = lsh经销商表Repository.findAllPermitByCTA(info.cusName);
        for (int i = 0; i < modellsit.size(); i++) {
            Lsh经销商表Model item = modellsit.get(i);
            mas.put(item.get经销商名(), item.getBmbs());
        }
        ma.put("Data", mas);
        return ma;
    }

    // 传入的 是大区
    public Map getBMBsCodeByBigAreaRole(ChangeCar info, String userName, String permit) {
        Map ma = new HashMap();
        Map mas = new HashMap();
        List<Lsh经销商表Model> modellsit = lsh经销商表Repository.findAllPermitBy大区(info.cusName);
        for (int i = 0; i < modellsit.size(); i++) {
            Lsh经销商表Model item = modellsit.get(i);
            mas.put(item.get经销商名(), item.getBmbs());
        }
        ma.put("Data", mas);
        return ma;
    }


    public Map getBMBsCodeByCTA(ChangeCar info, String userName, String permit) {
        Map ma = new HashMap();
        Map mas = new HashMap();
        List<String> modellsit = lsh经销商表Repository.findPermitAndAhBMBs(info.cusName);

        ma.put("Data", modellsit);
        return ma;
    }

    public Map getTOTALCodeByTOTAL(ChangeCar info, String userName, String permit) {
        Map ma = new HashMap();
        Map mas = new HashMap();
        if (info.actualValue.equalsIgnoreCase("TOTAL") || info.actualValue.equals("集团")) {
            logger.warn("get value for total.....");
            // 拿出 所有的 cta 大区 和 经销商
            List<String> result = lsh经销商表Repository.findBIgAreasLiSt();
            if (result != null && result.size() > 0) {
                ma.put("bigArea", result);
            } else {
                ma.put("bigArea", "无");
            }

            List<String> resultss = lsh经销商表Repository.findCTAlist();
            if (resultss != null && resultss.size() > 0) {
                ma.put("cta", resultss);
            } else {
                ma.put("cta", "无");
            }

            List<String> results = lsh经销商表Repository.findbmbslist();
            if (results != null && results.size() > 0) {
                ma.put("bmbs", results);
            } else {
                ma.put("bmbs", "无");
            }
        } else if (info.actualValue.equalsIgnoreCase("CTA")) {
            List<Lsh经销商表Model> rsults2 = lsh经销商表Repository.findAllPermitByCTA(info.actualValueCode);
            if (rsults2 != null && rsults2.size() > 0) {
                Lsh经销商表Model items = rsults2.get(0);
                Map<String, String> bigArea = new HashMap<>();
                bigArea.put("name", items.get大区());
                bigArea.put("nameEn", items.get大区en());
                ma.put("bigArea", bigArea);

                Map<String, String> cta = new HashMap<>();
                cta.put("name", info.actualValueCode);
                cta.put("nameEn", info.actualValueCode);
                ma.put("cta", cta);
            } else {
                ma.put("bigArea", this.isChineseLanguage()?"无":"None");
            }
            //ma.put("cta", info.actualValueCode);
        } else if (info.actualValue.equals("大区")) {
            List<String> result = lsh经销商表Repository.findPermitAndAhCtaPermit(info.actualValueCode);
            if (result != null && result.size() > 0) {
                ma.put("cta", result);
            } else {
                ma.put("cta", "无");
            }

            ma.put("bigArea", info.actualValueCode);
        } else {
            List<Lsh经销商表Model> result = lsh经销商表Repository.findAllPermitBy本店1(info.actualValueCode);
            Lsh经销商表Model oneitem = result.get(0);
            Map<String, String> bigArea = new HashMap<>();
            bigArea.put("name", oneitem.get大区());
            bigArea.put("nameEn", oneitem.get大区en());
            ma.put("bigArea", bigArea);
           /* if (oneitem != null) {
                Map<String, String> cta = new HashMap<>();
                cta.put("name", oneitem.getCta());
                cta.put("nameEn", oneitem.getCtaEn());
                ma.put("cta", cta);
            } else {
                Map<String, String> cta = new HashMap<>();
                cta.put("name", "CTA");
                cta.put("nameEn", "CTA");
                cta.put("cta", "其他cta");
                ma.put("cta", cta);
            }*/
        }
        mas.put("Data", ma);
        return mas;
    }


    @Transactional
    public ResultData saveNewCesar(List<SaveNewCesar> reqList, String operaAcct, String permit ) {

        ResultData resultData = new ResultData();
        resultData.setResult("true");
        resultData.setMessage("正常");
        Map<String,String> msgMap=new HashMap();
        StopWatch first=new StopWatch("first");
        try {
            Integer successCount = new Integer(0);
            Integer defeatedCount = new Integer(0);
            StringBuffer messages = new StringBuffer("车架号：");
            int lfon = 0;
            int vincode = 0;
            List<String> productNoList = new ArrayList<>(200);
            List<String> vinNoList = new ArrayList<>(200);
            //构造消息map
            msgMap.put("checkDaWANGZHENYANteMsg","");//数据检查消息
            msgMap.put("deleteMsg","");//删除信息消息
            msgMap.put("refuseInsertMsg","");//不予导入消息
            msgMap.put("defeatedMsg","");//失败消息
            msgMap.put("occupiedMsg","");//被他店占用消息
            //1.  检查数据准确性,将错误信息存入msgMap
            first.start("checkDateMsg");
            String checkDateMsg =  checkCesarDateList(  reqList,   productNoList,   vinNoList );
            first.stop();
            msgMap.put("checkDateMsg",checkDateMsg);
           //2.  如果LIVE上的生产号MAP不到CESAR上的生产号，车辆的LiVE批发日期和LiVE VSB财务状态都为空 则删除，将信息存入msgMap
            first.start("delete");
            Map deleteMap=deleteStockModel(permit, productNoList, operaAcct);
            msgMap.put("deleteMsg",String.format("库存匹配不到删除库存资源%s条。",Integer.parseInt(deleteMap.get("size").toString()))+deleteMap.get("msg").toString());
            first.stop();
            // 根据生产号，车架号找出库里的数据
            Map<Object, List> prodMap = getprodMap(productNoList);
            // 根据车架号，找出库里的数据
            Map<Object, List> vinMap = getvinMap(vinNoList);
            List<Lsh库存表Model> reInsertList = new ArrayList<>(500);
            List<Lsh库存表Model> reUpdateList = new ArrayList<>(500);

            //3.根据不同情况 处理数据
            first.start("A");
            for (SaveNewCesar req : reqList) {
                if (("LFON").equalsIgnoreCase(req.primaryStatus) || req.proDate == null) {
                    lfon++;
                    continue;
                }
                String    msg = null;
                switch (cesarType( prodMap, req)) {
                case 1: // 1 库中不存在生产号
                    msg = cesarNotProductNo(req, reInsertList, vinMap, permit, operaAcct, vincode);
                     break;
                case 2: // 2 库中存在生产号
                    msg = cesarHaveProductNo(req, reUpdateList, vinMap, prodMap, permit, operaAcct, vincode,msgMap);
                    break;
                case 3: //3 库中存在生产号  且   批发日期为空的    且财务状态为A
                    msg =  cesarVbsIsA(req, reUpdateList, vinMap, prodMap, permit, operaAcct, vincode);
                    break;
                default:
                    successCount++;
                    break;
                }
                if (msg != null) {
                    messages.append(msg);
                    defeatedCount++;
                } else {
                    vincode++;
                }
            }
            first.stop();
            // 保存新增，reInsertList中的库存编号就有值了
            first.start("SAVESTOCK");
            lsh库存表Repository.save(reInsertList);
            //保存更新
            lsh库存表Repository.save(reUpdateList);
            logdata.info("Cesar——insert——" + permit + "。list={}", JsonObjectUtils.writeAsJson(reInsertList));
            //保存可见级别
            insertStock(  reInsertList,  permit,  operaAcct);
            first.stop();
            //构造返回消息
           String resMsg= msgManufacture(msgMap, messages, defeatedCount , lfon,  reqList.size(),  vincode);
            resultData.setMessage(resMsg);
            logdata.info("Cesar——msg——" + permit + "。msg={}", resMsg);
        }
        catch (PersistenceException e) {
            Throwable cause = e.getCause();
            resultData.setResult("false");
            logger.error("cesar导入失败", e);
            if(cause instanceof org.hibernate.exception.ConstraintViolationException) {
            resultData.setMessage("Excel中重复车架号，请检查 ");
           }
           else if(cause instanceof org.hibernate.exception.SQLGrammarException) {
                resultData.setMessage("生产号不合法或有批发日期无车架号，导入失败");
            }
            else    resultData.setMessage("系统异常 保存失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        catch (Exception e) {
            resultData.setResult("false");
            resultData.setMessage("系统异常 保存失败");
            logger.error("cesar导入失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        System.out.println(first.prettyPrint());
        return resultData;
    }

    //构造消息
    private String msgManufacture(Map<String,String> msgMap,StringBuffer messages,int defeatedCount ,int lfon,int total,int success){
        if (defeatedCount != 0) {//失败条数消息
            msgMap.put("defeatedMsg",String.format("\n车架号冲突失败%s条数据", defeatedCount)+ messages.toString() + "在系统中已经存在，请检查EXCEL中该车架号与生产号是否正确，如果正确请联系售后;");
        }
        if (lfon != 0) {//不予导入消息
            msgMap.put("refuseInsertMsg",String.format("\n" + "EXCEL中primaryStatus为'LFON'或Confirmed Production Date为空不予导入%s条数据。", lfon));
        }
        //消息拼接，   共计**条，成功**条，车架号失败**条，不予**条，**条被挂车不能导不能删，数据错误**条，导入车辆它被占用
        String  resMsg=String.format("共计%s条，成功保存%s条数据。 \n", total, success)+msgMap.get("defeatedMsg")
                +msgMap.get("refuseInsertMsg")+msgMap.get("deleteMsg") +msgMap.get("checkDateMsg") +msgMap.get("occupiedMsg");
        return  resMsg;
    }
    private int cesarType(  Map<Object, List> prodMap,SaveNewCesar req ){
        if (!prodMap.containsKey(req.productNo)) {// 1 库中不存在生产号
           return 1;
        }
        // 2 库中存在生产号
        else if (prodMap.get(req.productNo).get(8) == null &&
                (prodMap.get(req.productNo).get(9) == null || !("A").equalsIgnoreCase(prodMap.get(req.productNo).get(9).toString()))) {
          return 2;
        }
        //3 库中存在生产号  且   批发日期为空的    且财务状态为A
        else if (prodMap.get(req.productNo).get(8) == null &&
                (prodMap.get(req.productNo).get(9) != null && ("A").equalsIgnoreCase(prodMap.get(req.productNo).get(9).toString()))) {
                 return 3;
        } else {
         return 4;
        }
    }

    //检查Cesar数据合法性，若不合法，移除不合法数据并记录
    private String checkCesarDateList(List<SaveNewCesar> reqList, List<String> productNoList, List<String> vinNoList  ){
        String errorProd="";
        String errorProDate="";
        List<Integer> deleteProuctList=new ArrayList<>();
        for (int i=0;i<reqList.size();i++) {
            SaveNewCesar req=reqList.get(i);
            String a=req.productNo.substring(0,1);
            String productNo=req.productNo;
            if("#".equals(a)||"#".equals(a)){//除去生产号里的#
                //   String debug=productNo.substring(1,productNo.length()-1);
                req.productNo=productNo.substring(1,productNo.length());
            }
            if(req.productNo.length()<10){ //校验 生产号 长度
                errorProd=errorProd+req.productNo+",";
                deleteProuctList.add(i);
                continue;
            }
            if(req.wholesaleDate!=null&&(req.VIN==null||"".equals(req.VIN))){//有批发日期 且 无车架号
                errorProDate=errorProDate+req.productNo+",";
                deleteProuctList.add(i);
                continue;
            }
            productNoList.add(req.productNo);
            vinNoList.add(req.VIN);
        }
        for(int a=deleteProuctList.size()-1;a>=0;a--){//移除不合法生产号
            int b=deleteProuctList.get(a);
            reqList.remove(b);
        }
        if (!"".equals(errorProd)){
            errorProd=" 生产号："+errorProd+"不合法（长度异常）。";}
        if (!"".equals(errorProDate)){
            errorProDate=" 生产号："+errorProDate+"的车辆有批发日期，车架号不允许为空。";}
            return errorProd+errorProDate;
    }

    private void insertStock(List<Lsh库存表Model> reInsertList,String permit,String operaAcct){
        boolean isShow = repository.getIsShow(permit);
        ArrayList<Lsh库存内部可见Model> list=new ArrayList<>();
        for (Lsh库存表Model lsh库存表Model : reInsertList) {
            if (isShow) {
                Lsh库存内部可见Model lsh库存内部可见Model = new Lsh库存内部可见Model();
                lsh库存内部可见Model.set库存编号(lsh库存表Model.get库存编号());
                lsh库存内部可见Model.set内部可见角色("SC/CDO可见");
                lsh库存内部可见Model.set更新账号(operaAcct);
                // 在LSH库存可见表插入一条数据
                list.add(lsh库存内部可见Model);
            }
        }
        lsh库存内部可见Repository.save(list);
    }

    // 根据生产号，车架号找出库里的数据
    private Map<Object, List> getprodMap(List productNoList) {
        List prodList = repository.getExistProductNoNew(productNoList);
        Map<Object, List> prodMap = new HashMap<>();
        for (Object o : prodList) {
            Map m = (Map) o;
            List<Object> l = new ArrayList<>();
            l.add(0, m.get("库存编号"));
            l.add(1, m.get("生产号"));
            l.add(2, m.get("车架号"));
            l.add(3, m.get("开票时间"));
            l.add(4, m.get("调车物流状态"));
            l.add(5, m.get("出库日期"));
            l.add(6, m.get("二次PDI完成日期"));
            l.add(7, m.get("入库日期"));
            l.add(8, m.get("批发日期"));
            l.add(9, m.get("VSB财务状态"));
            l.add(10, m.get("车辆零售状态"));
            l.add(11, m.get("报价编号"));
            l.add(12, m.get("所属经销商"));
            prodMap.put(m.get("生产号"), l);
        }
        return prodMap;
    }

    // 根据车架号，车架号找出库里的数据
    private Map<Object, List> getvinMap(List vinNoList) {
        List vinList = repository.getExistVinNew(vinNoList);
        Map<Object, List> vinMap = new HashMap<>();
        for (Object o : vinList) {
            Map m = (Map) o;
            List<Object> l = new ArrayList<>();
            l.add(0, m.get("库存编号"));
            l.add(1, m.get("生产号"));
            l.add(2, m.get("车架号"));
            l.add(3, m.get("开票时间"));
            l.add(4, m.get("调车物流状态"));
            l.add(5, m.get("出库日期"));
            l.add(6, m.get("二次PDI完成日期"));
            l.add(7, m.get("入库日期"));
            l.add(8, m.get("批发日期"));
            l.add(9, m.get("VSB财务状态"));
            l.add(10, m.get("车辆零售状态"));
            l.add(11, m.get("报价编号"));
            l.add(12, m.get("所属经销商"));
            vinMap.put(m.get("车架号"), l);
        }
        return vinMap;
    }

    //caser 导入 库中不存在生产号
    private String cesarNotProductNo(SaveNewCesar req, List reInsertList, Map<Object, List> vinMap, String permit, String operaAcct, Integer successCount) {
        // 1.1  req.vin非null且库中存在相同的vin码时，作为不合法输入处理
        if (req.VIN != null && vinMap.containsKey(req.VIN)) {
            return cesarError(req.VIN);
        }
        // 1.2    req.vin为null，或库中不存在重复的vin码时，作为新车入库
        else {
            if (!("LFON").equalsIgnoreCase(req.primaryStatus)) {//Primary Status为LFON则不导入；
                req.status = getCarTransportStatus(req.status, null, Arrays.asList(null, null, null, null));
                Lsh库存表Model model = constructInsertCarStockModel(permit, req, operaAcct, ++successCount);
                reInsertList.add(model);
            }
        }

        return null;
    }

    //caser导入，库中存在生产号
    private String cesarHaveProductNo(SaveNewCesar req, List reUpdateList, Map<Object, List> vinMap, Map<Object, List> prodMap, String permit, String operaAcct, Integer successCount, Map<String,String> msgMap) {
        List temp = (List) prodMap.get(req.productNo);
        String occupiedMsg=msgMap.get("occupiedMsg");
        if (permit.equals(temp.get(12))||(temp.get(11) == null && (temp.get(10)==null||"未卖".equals(temp.get(10))))) {//自家车或者不被挂车的别家车，则进行更新
            // 2.1 req.vin为null时，不管以前是什么值，将vin修改为虚拟车架号，传入库存编号，更新记录
            if (req.VIN == null) {
                cesarHaveProductNoNotVin(req, reUpdateList, prodMap, permit, operaAcct, successCount);
                return null;
            } else {//2.2 req.vin非null
                return cesarHaveProductNoHaveVin(req, reUpdateList, vinMap, prodMap, permit, operaAcct, successCount);
            }
        }
        if(!permit.equals(temp.get(12))&&! "未卖".equals(temp.get(10) )){//非自家且被挂车，则提示
            String permitOld=lsh经销商表Repository.findNameByPermit( temp.get(12).toString());
            occupiedMsg=occupiedMsg+"生产号："+req.productNo+"对应车辆已被"+permitOld+"店锁定,"+"请联系"+permitOld+"店解除资源锁定。\n";
            msgMap.put("occupiedMsg",occupiedMsg);
            return null;
        }
        return  null;
    }

    //cesar导入库中存在生产号，且传入车架号为空，不管以前是什么值，将vin修改为虚拟车架号，传入库存编号，更新记录
    private void cesarHaveProductNoNotVin(SaveNewCesar req, List reUpdateList, Map<Object, List> prodMap, String permit, String operaAcct, Integer successCount) {
        List temp = (List) prodMap.get(req.productNo);
        // 库中该车非开票且非调车状态时，更新
        //  if (temp.get(3) == null && temp.get(4) == null) {
        req.status = getCarTransportStatus(req.status, null, Arrays.asList(temp.get(5), temp.get(6), temp.get(7), temp.get(8)));
        Lsh库存表Model model = constructUpdateCarStockModel(permit, (Integer) temp.get(0), req, operaAcct, ++successCount);
        reUpdateList.add(model);
        //  }
    }

    //cesar导入库中存在生产号，且传入车架号不为空
    private String cesarHaveProductNoHaveVin(SaveNewCesar req, List reUpdateList, Map<Object, List> vinMap, Map<Object, List> prodMap, String permit, String operaAcct, Integer successCount) {
        // 2.2.1库中存在相同的vin码
        if (vinMap.containsKey(req.VIN)) {
            // 2.2.1.1两条数据库存编号相同，更新记录
            if (prodMap.get(req.productNo).get(0).equals(vinMap.get(req.VIN).get(0))) {
                List prodTemp = (List) prodMap.get(req.productNo);
                List vinTemp = (List) prodMap.get(req.productNo);
                if (prodTemp.get(0).equals(vinTemp.get(0))) {
                    List temp = (List) prodMap.get(req.productNo);
                    // 库中该车非开票且非调车状态时，更新
                    //if (temp.get(3) == null && temp.get(4) == null) {
                    req.status = getCarTransportStatus(req.status, null, Arrays.asList(temp.get(5), temp.get(6), temp.get(7), temp.get(8)));
                    Lsh库存表Model model = constructUpdateCarStockModel(permit, (Integer) temp.get(0), req, operaAcct, ++successCount);
                    reUpdateList.add(model);
                    // }
                }
            } else {
                // 2.2.1.2两条数据库存编号不同，作为不合法输入处理
                return cesarError(req.VIN);
            }
        } else {
            // 2.2.2库中不存在相同的vin码，更新数据
            List temp = (List) prodMap.get(req.productNo);
            // 库中该车非开票且非调车状态时，更新
            // if (temp.get(3) == null && temp.get(4) == null) {
            req.status = getCarTransportStatus(req.status, null, Arrays.asList(temp.get(5), temp.get(6), temp.get(7), temp.get(8)));
            Lsh库存表Model model = constructUpdateCarStockModel(permit, (Integer) temp.get(0), req, operaAcct, ++successCount);
            reUpdateList.add(model);
            //}
        }

        return null;
    }

    //没有批发日期且财务状态为A，
    private String cesarVbsIsA(SaveNewCesar req, List reUpdateList, Map<Object, List> vinMap, Map<Object, List> prodMap, String permit, String operaAcct, Integer successCount) {
        List temp = (List) prodMap.get(req.productNo);// 取生产号对应的库存编号
        Integer stockId=(Integer) temp.get(0);
        Lsh库存表Model model = lsh库存表Repository.findOne(stockId);
        if (vinMap.containsKey(req.VIN)) {
            // 2.2.1.1两条数据库存编号相同，更新记录
            if (prodMap.get(req.productNo).get(0).equals(vinMap.get(req.VIN).get(0))) {
                cesarVbsIsA(  req,   reUpdateList,  (Integer) temp.get(0),  permit,operaAcct,++successCount);
            } else { // 2.2.1.2两条数据库存编号不同，作为不合法输入处理
                return cesarError(req.VIN);
            }
        }
        else{
            cesarVbsIsA(  req,   reUpdateList,  (Integer) temp.get(0),  permit,operaAcct,++successCount);
        }
        return null;
    }

    //没有批发日期且财务状态为A，导入时，若所属经销商等于当前经销商，则更新 批发日期和预计付款日期
    private void cesarVbsIsA(SaveNewCesar req, List reUpdateList,Integer stockId,String permit,String operaAcct,Integer count){
        Lsh库存表Model model = lsh库存表Repository.findOne(stockId);
        if (permit.equals(model.get所属经销商())) {//更新 批发付款日期

            if (!"".equals(req.engineNo) && req.engineNo != null) {// 发动机号
                model.set发动机号(req.engineNo);
            }
            if (req.carNo != null) {//存入车型编号
                model.set车型编号(req.carNo);
            }
            if (!"".equals(req.VIN) && req.VIN != null) {//存入车架号
                model.set车架号(req.VIN);
            }else {
                String str1[] = operaAcct.split("@");
                String str2 = "Email";
                if (str1.length > 0) {
                    str2 = str1[0];
                    if (str2.length() > 18) {
                        str2 = str2.substring(0, 18);
                    }
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                String currentTime = sdf.format(new Date());
                // IRISTechNV_'+操作账号@左侧部分(如果没有@,账号取'Email',如果取完长度大于18个字符，则取左侧18个字符)+年月日时分秒+本次导入的序号
                String VIN = "";
                if (req.VIN != null) {
                    VIN = req.VIN;
                } else {
                    ++count;
                    VIN = "IRISTechNV_" + str2 + "_" + currentTime + "_" + count;
                }
                model.set车架号(VIN);
            }

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            if (model.get批发日期() == null || "0000-00-00".equals(sdf.format(model.get批发日期()))) {
                Calendar cal = Calendar.getInstance();
                if (!"".equals(req.wholesaleDate) && req.wholesaleDate != null) {
                    cal.setTime(req.wholesaleDate);
                    cal.add(Calendar.DATE, 15);
                    model.set批发付款到期日(cal.getTime());
                }
                model.set批发日期(req.wholesaleDate);
                long day = 0;
                Date endDate = new Date();
                if (model.get批发日期() != null) {//计算库存
                    day = (endDate.getTime() - model.get批发日期().getTime()) / (24 * 60 * 60 * 1000);
                    model.set库龄天数(new Long(day).intValue());
                }
            }
            reUpdateList.add(model);
        }
    }


    //cesar  导入 报错
    private String cesarError(String vin) {
        return String.format("%s，", vin);
    }

    /*
   * Cesar更新库存表记录的方法
   * @param permit 许可
   * @param stockId 库存编号
   * @param req 请求json
   * @return 准备更新的model
   */
    private Lsh库存表Model constructUpdateCarStockModel(String permit, Integer stockId, SaveNewCesar req, String operaAcct, Integer count) {
        Lsh库存表Model model = lsh库存表Repository.findOne(stockId);
        logdata.info("Cesar——update ——" + permit + "。 oldMode={}", JsonObjectUtils.writeAsJson(model));
        String abbc = JsonObjectUtils.writeAsJson(model);
        //logdata.debug("Cesar——updatepermit ——new"+permit, JsonObjectUtils.writeAsJson(model.get所属经销商()));
        if (!"".equals(req.productNo) && req.productNo != null) {
            String a=req.productNo.substring(0,1);
            String productNo=req.productNo;
            if("#".equals(a)||"#".equals(a)){
                model.set生产号(productNo.substring(1,productNo.length()-1));
            }else {
                model.set生产号(req.productNo);
            }
        }
        if (req.carNo != null) {
            model.set车型编号(req.carNo);
        }
        if (req.proDate != null) {
            model.set生产日期(req.proDate);
        }
        if (!"".equals(req.VIN) && req.VIN != null) {
            model.set车架号(req.VIN);
        } else {
            String str1[] = operaAcct.split("@");
            String str2 = "Email";
            if (str1.length > 0) {
                str2 = str1[0];
                if (str2.length() > 18) {
                    str2 = str2.substring(0, 18);
                }
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String currentTime = sdf.format(new Date());
            // IRISTechNV_'+操作账号@左侧部分(如果没有@,账号取'Email',如果取完长度大于18个字符，则取左侧18个字符)+年月日时分秒+本次导入的序号
            String VIN = "";
            if (req.VIN != null) {
                VIN = req.VIN;
            } else {
                ++count;
                VIN = "IRISTechNV_" + str2 + "_" + currentTime + "_" + count;
            }
            model.set车架号(VIN);
        }
        if (!"".equals(req.engineNo) && req.engineNo != null) {
            model.set发动机号(req.engineNo);
        }
        if (!"".equals(req.colorCode) && req.colorCode != null) {
            model.set颜色代码(req.colorCode);
        }
        if (!"".equals(req.color) && req.color != null) {
            model.set颜色(req.color);
        }
        if (!"".equals(req.innerCode) && req.innerCode != null) {
            model.set内饰代码(req.innerCode);
        }
        if (!"".equals(req.inner) && req.inner != null) {
            model.set内饰(req.inner);
        }
        if (req.orderDate != null) {
            model.set厂家确认订单日期(req.orderDate);
        }
        if (req.orderDate != null) {
            model.set厂家确认订单日期(req.orderDate);
        }
        if (!"".equals(req.status) && req.status != null) {
            // model.set车辆物流状态(req.status);
        }
        model.set港口代码(req.portId);
        model.set实际到港日期(req.realPortDate);
        model.set预计到港日期(req.aimPortDate);
        model.setHold日期(req.holdDate);
        model.set港口名称(req.portName);
        model.setBi车款标配Msrp含税(req.BIPrice);
        //计算 批发付款日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String currentTime = sdf.format(new Date());
        if (model.get批发日期() == null || "0000-00-00".equals(sdf.format(model.get批发日期()))) {
            Calendar cal = Calendar.getInstance();
            if (!"".equals(req.wholesaleDate) && req.wholesaleDate != null) {
                cal.setTime(req.wholesaleDate);
                cal.add(Calendar.DATE, 15);
                model.set批发付款到期日(cal.getTime());
            }
        }
        Itask基础设置ModelPK pkson = new Itask基础设置ModelPK();
        pkson.set许可(permit);
        pkson.set设置项目("本店车辆他店可见级别");
        Itask基础设置Model bigCitypermit = itask基础设置Repository.findOne(pkson);
        if (bigCitypermit != null) {
            String zhi = bigCitypermit.get值();
            if (zhi != null) {
                if (zhi.equals("0")) {
                    model.set外部可见级别("全国可见");
                } else if (zhi.equals("1")) {
                    model.set外部可见级别("大区可见");
                } else if (zhi.equals("2")) {
                    model.set外部可见级别("小区可见");
                } else if (zhi.equals("3")) {
                    model.set外部可见级别("CTA可见");
                } else if (zhi.equals("4")) {
                    model.set外部可见级别("外部不可见");
                } else {
                    model.set外部可见级别("外部不可见");
                }
            } else {
                model.set外部可见级别("外部不可见");
            }
        } else {
            model.set外部可见级别("外部不可见");
        }
        model.set批发日期(req.wholesaleDate);
        //计算库龄
        long day = 0;
        Date endDate = new Date();
        if (model.get批发日期() != null) {
            day = (endDate.getTime() - model.get批发日期().getTime()) / (24 * 60 * 60 * 1000);
            model.set库龄天数(new Long(day).intValue());
        }
        model.set采购批发商(permit);
        // 新添加的字段，归档状态，默认“00”表示未归档
        model.setCarState("00");
        model.set所属经销商(permit);
        model.set采购批发商(permit);
        if("1".equals(model.getIsDelete().toString())){
            model.set车辆零售状态("未卖");
        }
        model.setIsDelete((byte) 0);
        model.setVsb财务状态("O");
        model.setDeleteUser(null);
        logdata.info("Cesar——update ——" + permit + "。 newMode={}", JsonObjectUtils.writeAsJson(model));
        return model;
    }

    /*
      * Cesar向库存表中添加新记录
      * @param permit 许可
      * @param req 请求json
      * @param isShow
      * @param operaAcct
      * @return
      */
    private Lsh库存表Model constructInsertCarStockModel(String permit, SaveNewCesar req, String operaAcct, Integer count) {
        Lsh库存表Model model = new Lsh库存表Model();
        String a=req.productNo.substring(0,1);
        String productNo=req.productNo;
        if("#".equals(a)||"#".equals(a)){
            model.set生产号(productNo.substring(1,productNo.length()-1));
        }else {
            model.set生产号(req.productNo);
        }
        model.set车型编号(req.carNo);
        model.set生产日期(req.proDate);
        String str1[] = operaAcct.split("@");
        String str2 = "Email";
        if (str1.length > 0) {
            str2 = str1[0];
            if (str2.length() > 18) {
                str2 = str2.substring(0, 18);
            }
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String currentTime = sdf.format(new Date());
        // IRISTechNV_'+操作账号@左侧部分(如果没有@,账号取'Email',如果取完长度大于18个字符，则取左侧18个字符)+年月日时分秒+本次导入的序号
        String VIN = "";
        if (req.VIN != null) {
            VIN = req.VIN;
        } else {
            ++count;
            VIN = "IRISTechNV_" + str2 + "_" + currentTime + "_" + count;
        }
        //计算 批发付款日期
        if (model.get批发日期() == null || "0000-00-00".equals(sdf.format(model.get批发日期()))) {
            Calendar cal = Calendar.getInstance();
            if (!"".equals(req.wholesaleDate) && req.wholesaleDate != null) {
                cal.setTime(req.wholesaleDate);
                cal.add(Calendar.DATE, 15);
                model.set批发付款到期日(cal.getTime());
            }
        }
        //计算库龄
        long day = 0;
        Date endDate = new Date();
        model.set批发日期(req.wholesaleDate);
        if (model.get批发日期() != null) {
            day = (endDate.getTime() - model.get批发日期().getTime()) / (24 * 60 * 60 * 1000);
            model.set库龄天数(new Long(day).intValue());
        }
        model.set港口代码(req.portId);
        model.set实际到港日期(req.realPortDate);
        model.set预计到港日期(req.aimPortDate);
        model.setHold日期(req.holdDate);
        model.set车架号(VIN);
        model.set发动机号(req.engineNo);
        model.set颜色代码(req.colorCode);
        model.set颜色(req.color);
        model.set内饰代码(req.innerCode);
        model.set内饰(req.inner);
        model.set厂家确认订单日期(req.orderDate);
        // model.set车辆物流状态(req.status);
        model.set采购批发商(permit);
        model.set港口名称(req.portName);
        model.setBi车款标配Msrp含税(req.BIPrice);
        model.set实际Msrp含税(req.BIPrice);
        // 新添加的字段，归档状态，默认“00”表示未归档
        model.setCarState("00");
        //默认外部可见级别'外部不可见',所属经销商：许可。
        Itask基础设置ModelPK pkson = new Itask基础设置ModelPK();
        pkson.set许可(permit);
        pkson.set设置项目("本店车辆他店可见级别");
        Itask基础设置Model bigCitypermit = itask基础设置Repository.findOne(pkson);
        if (bigCitypermit != null) {
            String zhi = bigCitypermit.get值();
            if (zhi != null) {
                if (zhi.equals("0")) {
                    model.set外部可见级别("全国可见");
                } else if (zhi.equals("1")) {
                    model.set外部可见级别("大区可见");
                } else if (zhi.equals("2")) {
                    model.set外部可见级别("小区可见");
                } else if (zhi.equals("3")) {
                    model.set外部可见级别("CTA可见");
                } else if (zhi.equals("4")) {
                    model.set外部可见级别("外部不可见");
                } else {
                    model.set外部可见级别("外部不可见");
                }
            } else {
                model.set外部可见级别("外部不可见");
            }
        } else {
            model.set外部可见级别("外部不可见");
        }
        // model.set外部可见级别("外部不可见");
        model.set所属经销商(permit);
        model.set车辆零售状态("未卖");
        model.setIsDelete((byte) 0);
        model.setVsb财务状态("O");
        model.setDeleteUser(null);
        return model;
    }
    @Override
    public ResultData saveCesarAndDmsExcel(String operaAcct, String permit, MultipartFile file,String name) {
        ResultData resultData = new ResultData();
        saveCesarAndDmsFile(file,permit,name);
        resultData.setResult("true");
        resultData.setMessage("正常");
      return  resultData;
    }
    //备份上传的文件
    private  void  saveCesarAndDmsFile(MultipartFile file,String permit,String name ){
        String path=  fileRepository.uploadFile(file, permit,name);
        logdata.info("Cesar——fileName——" + permit + "。filePath={}", path);
    }


    //DMS导入
    @Transactional
    public ResultData saveNewDMS(List<SaveNewDms> reqList, String operaAcct, String permit ) {
        ResultData resultData = new ResultData();
        resultData.setResult("true");
        resultData.setMessage("正常");
        logdata.info("DMS——allInfo——" + permit + "。list={}", JsonObjectUtils.writeAsJson(reqList));
        try {
            Integer defeatedCountA = 0;
            Integer defeatedCountB = 0;
            StringBuffer messagesNoCesar = new StringBuffer("生产号：");
            StringBuffer msgMsrpError = new StringBuffer("生产号：");
            String msgA = "";//noCesar
            String msgB = "";//MsrpError
            String errorProd="";
            //获取 车型 信息
            List carTpyeList = repository.findAllCarType();
            List<String> productNoList = new ArrayList<>();
            List<Integer> deleteProuctList=new ArrayList<>();
            for (int i=0;i<reqList.size();i++) {
                SaveNewDms req=reqList.get(i);
                String a=req.productNo.substring(0,1);
                String productNo=req.productNo;
                if("#".equals(a)||"#".equals(a)){
                    req.productNo=productNo.substring(1,productNo.length());
                }
                if(req.productNo.length()<10){ //校验 生产号 长度
                    errorProd=errorProd+req.productNo+",";
                    deleteProuctList.add(i);
                    continue;
                }
                productNoList.add(req.productNo);
            }
            for(int a=deleteProuctList.size()-1;a>=0;a--){//移除不合法生产号
                int b=deleteProuctList.get(a);
                reqList.remove(deleteProuctList.get(a));
            }
            if (!"".equals(errorProd)){
                errorProd=" 生产号："+errorProd+"不合法（长度异常）。";}
            Map<Object, Lsh库存表Model> prodMap = getHaveStockList(productNoList);
            List<Lsh库存表Model> reUpdateList = new ArrayList<>(500);
            for (SaveNewDms req : reqList) {
                msgA = "";
                msgB = "";
                // 库中不存在该生产号
                if (!prodMap.containsKey(req.productNo)||"1".equals(prodMap.get(req.productNo).getIsDelete())) {// 库中不存在  或已删除
                    //在返回msg中增加 不存在 请导入该车辆CESAR
                    msgA = DMSError(req.productNo);
                } else if (prodMap.get(req.productNo).getVsb财务状态() == null || !("A").equalsIgnoreCase(prodMap.get(req.productNo).getVsb财务状态())) { //DMS导入库中存在生产号，且库中财务状态不为A
                    if (("A").equalsIgnoreCase(req.VBSState)) {//传入财务状态为A
                        //传入MSRP 校验    0.9<= 车辆的采购价（含税)/车辆MSRP(含税)<=0.98
                        msgB = inVBSSateIsA(req, prodMap, reUpdateList, carTpyeList, permit);
                    } else {// 传入财务状态不为A
                        Lsh库存表Model model = dmsUpdateCarStockModel(prodMap.get(req.productNo), req, permit);
                        model = updateCarType(model, carTpyeList, req);//修正该车辆信息
                        reUpdateList.add(model);
                    }
                }
                if (!msgA.equals("")) {
                    defeatedCountA++;
                    messagesNoCesar.append(msgA).append(" ");
                }
                if (!msgB.equals("")) {
                    defeatedCountB++;
                    msgMsrpError.append(msgB).append(" ");
                }
            }
            if (defeatedCountA != 0) {
                msgA = messagesNoCesar.toString() + " 在系统中不存在，请检查EXCEL中该车是否导入CESAR，如果导入请联系售后;\n";
            }
            if (defeatedCountB != 0) {
                msgB = msgMsrpError.toString() + " 车辆MSRP不正确，请到DMS修正后重新导入;\n";
            }
            int noUpdata = reqList.size() - (defeatedCountA + defeatedCountB + reUpdateList.size());
            String msgC = String.format("库中财务状态为A，不做更新%s条。", noUpdata);
            resultData.setMessage(String.format(" 添加%s条数据，失败%s条数据。", reUpdateList.size(), (defeatedCountA + defeatedCountB)) + "\n" + msgA + msgB + msgC);
            lsh库存表Repository.save(reUpdateList);
        } catch (Exception e) {
            resultData.setResult("false");
            resultData.setMessage("系统异常 保存失败");
            logger.error("DMS导入失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return resultData;


    }

    //输入财务状态为A
    private String inVBSSateIsA(SaveNewDms req, Map<Object, Lsh库存表Model> prodMap, List<Lsh库存表Model> reUpdateList, List carTpyeList, String permit) {
        //传入MSRP 校验    0.9<= 车辆的采购价（含税)/车辆MSRP(含税)<=0.98   且   车不能大于500万
        int fact=req.factMSRPTax.compareTo(BigDecimal.valueOf(5000000));
        int buy=req.buyPriceTax.compareTo(BigDecimal.valueOf(5000000));
        double a = req.buyPriceTax.doubleValue();
        double b = req.factMSRPTax.doubleValue();
        if (a!=0&&b!=0&&fact==-1&&buy==-1) {

            double flog = a / b;
            // BigDecimal f = req.buyPriceTax.divide(req.factMSRPTax,3, BigDecimal.ROUND_UNNECESSARY);
            // double flog = f.doubleValue();
            if (flog < DefaultValueConstant.DMS_MIN_PRICE_RATE || flog > DefaultValueConstant.DMS_MAX_PRICE_RATE) {//若大于0.98  小于0.9则报错
                return DMSErrorPrice(req.productNo);
            } else {
                Lsh库存表Model model = dmsUpdateCarStockModel(prodMap.get(req.productNo), req, permit);
                model = updateCarType(model, carTpyeList, req);//修正该车辆信息
                reUpdateList.add(model);
            }
        } else {//为0报错
            return DMSErrorPrice(req.productNo);
        }
        return "";
    }

    // 根据生产号，查出库存数据
    private Map<Object, Lsh库存表Model> getHaveStockList(List<String> productNoList) {

        List<Lsh库存表Model> prodModelList = lsh库存表Repository.getProdModelList(productNoList);
        //   List prodList = repository.getHaveProductNoStock(productNoList);
        Map<Object, Lsh库存表Model> prodMap = new HashMap<>();
        for (Lsh库存表Model a : prodModelList) {
            Lsh库存表Model req = a;
            prodMap.put(req.get生产号(), req);
        }
        return prodMap;
    }

    private String DMSError(String productNo) {
        return String.format(" %s，", productNo);

    }

    private String DMSErrorPrice(String productNo) {
        return String.format("  %s， ", productNo);
    }

    private Lsh库存表Model dmsUpdateCarStockModel(Lsh库存表Model model, SaveNewDms req, String permit) {
        req.status = getCarTransportStatus(req.status, req.startProduDate, Arrays.asList(model.get出库日期(), model.get二次Pdi完成日期(), model.get入库日期(), model.get批发日期()));
        logdata.info("DMS——updateBefo——" + permit + "。model={}", JsonObjectUtils.writeAsJson(model));
        model.set欧版底盘号(req.chassisNo);
        model.setVsb号(req.VSB);
        model.set原厂配置(req.factoryConfig);
        model.set加配配置(req.addConfig);
        model.set加配价格含税(req.addConfigPrice);
        model.set采购价格含税(req.buyPriceTax);
        model.set采购价格未税(req.buyPrice);
        model.set标配Msrp含税(req.standardMSRPTax);
        model.set实际Msrp含税(req.factMSRPTax);
        model.setVsb财务状态(req.VBSState);
        model.set预计下线日期(req.expectRollDate);
        model.set批发商(req.wholesaler);
        model.set颜色(req.color);
        model.set颜色代码(req.colorCode);
        model.set内饰(req.inner);
        model.set内饰代码(req.innerCode);
        model.set车辆物流状态(req.status);
        logdata.info("DMS——updateAfter——" + permit + "。model={}", JsonObjectUtils.writeAsJson(model));
        return model;
    }
    //获取车辆的LiVE批发日期和LiVE VSB财务状态都为空  Map不到就删除
    private Map deleteStockModel(String permit, List<String> productNoList, String username) {
        Map result=new HashMap();
        List<Lsh库存表Model> prodList = lsh库存表Repository.getStockModelList(permit); //获取车辆的LiVE批发日期和LiVE VSB财务状态都为空  的车辆
        List<Lsh库存表Model> deleList = new ArrayList<>(500);
        Map<String, String> prodMap = new HashMap<>();
        String msg="";
        for (String a : productNoList) {// j将cesar  生产号，放入key
            prodMap.put(a, a);
        }
        for (Lsh库存表Model model : prodList) {//循环比较
            if (!prodMap.containsKey(model.get生产号()) &&(model.getIsDelete()==null|| (model.getIsDelete()!=null&& model.getIsDelete().toString().equals("0")))) {   //库存的生产号  不在CESAR里  则删除
                try {
                    if (model.get报价编号() != null) {
                        报价单表Model 报价单表Model = i报价单表Repository.findBy报价编号(model.get报价编号());
                        String scCode = 报价单表Model.get销售顾问();
                        String name=用户Repository.findNameameCnById(scCode).toString();
                        if (!"未卖".equals(model.get车辆零售状态())) {//发消息
                            msg=msg+"生产号："+model.get生产号()+"对应车辆资源已被销售顾问"+name+"锁定，请解除锁定后在调配车辆资源。\n";
                            顾客记录汇总Model r = 顾客记录汇总repository.findOne(报价单表Model.get顾客编号());
                            SendMsgRoleUtil.sendMsgBySale(username, 报价单表Model, r, MessageContext.getDeleteStock(model.get车架号(), r.get顾客姓名()), null);
                        }
                    }else{
                        model.setIsDelete((byte) 1);
                        model.setDeleteUser(username);
                        deleList.add(model);
                    }
                } catch (Exception e) {
                    logger.error("cesar删除消息发送失败", e);
                }
            }
        }
        lsh库存表Repository.save(deleList);
        logdata.info("Cesar——delete——" + permit + " 。deletelist={}", JsonObjectUtils.writeAsJson(deleList));
        result.put("size",deleList.size());
        result.put("msg",msg);
        return result;
    }

    //DMS车辆  车型调整
    private Lsh库存表Model updateCarType(Lsh库存表Model model, List carTpyeList, SaveNewDms req) {

        List<List> carType = new ArrayList();//暂存 传入 车型  对应 TYPE=2 的值
        //Lsh车型Model carTypeModel=lsh车型Repository.findOne(model.get车型编号());//取当前库存的车型
        for (Object o : carTpyeList) { // 车型编号,a.`Build_date`,Type,Variant
            Map m = (Map) o;
            String variant = m.get("Variant").toString();
            if (req.variant.equals(variant)) {
                List<Object> l = new ArrayList<>();
                l.add(m.get("车型编号"));
                l.add(m.get("Build_date"));
                l.add(m.get("Type"));
                l.add(m.get("Variant"));
                l.add(m.get("原厂配置"));
                carType.add(l);
            }
        }
        List<List> carTypeFactoryConfig = new ArrayList<>();
        for (List a : carType) {//循环比较原厂配置//储存原厂配置相等的
            if (a.size() != 0) {

                if (a.get(4) == null) {
                    continue;
                }
                String[] factory = a.get(4).toString().split(",");
                for (int i = 0; i < factory.length; i++) {
                    if (req.factoryConfig != null && !factory[i].equals("")&&req.factoryConfig.contains(factory[i])) {
                        carTypeFactoryConfig.add(a);
                        break;
                    }
                }
            }
        }
        if (carTypeFactoryConfig.size() != 0) {
            if (carTypeFactoryConfig.size() == 1) {//为一条 则修正
                model.set车型编号((int) carTypeFactoryConfig.get(0).get(0));
            } else {  //不为一条 则取  生产日期大于库中BulidDate  的  库存修正
                for (List a : carTypeFactoryConfig) {//以此循环  取  build  大于
                    Date nowBulidDate = (Date) a.get(1);//车型表中的Build
                    if (nowBulidDate != null && model.get生产日期() != null && model.get生产日期().getTime() > nowBulidDate.getTime()) {//库存表的生产日期
                        model.set车型编号((int) a.get(0));
                    }
                }
            }
        }
        return model;
    }


    @Override
    public ResultData getDeleteNewCesarList(RequestBase request, String userName, String permit) {
        ResultData resultData = new ResultData("false", null, null);
        try {
            resultData.setPageData(repository.findAllStock(request, permit));
            resultData.setResult("true");
            resultData.setMessage("成功");
        } catch (Exception e) {
            System.out.print(e);
            resultData.setMessage("获取失败");
            logger.error("换车列表", e);
        }
        return resultData;

    }

    @Override
    public ResultData deleteNewCesarList(List<Integer> stockIdList, String userName, String permit) {
        ResultData resultData = new ResultData("false", null, null);
        try {
            List<Lsh库存表Model> stockList = lsh库存表Repository.findStockListByStockId(stockIdList);
            List<Lsh库存表Model> updateStockList = new ArrayList<>(200);
            for (Lsh库存表Model model : stockList) {
                if (permit.equals(model.get所属经销商())) {
                    model.setIsDelete((byte) 1);
                    model.setDeleteUser(userName);
                    updateStockList.add(model);
                }
            }
            lsh库存表Repository.save(updateStockList);
            resultData.setResult("true");
            resultData.setMessage("删除成功");
        } catch (Exception e) {
            System.out.print(e);
            resultData.setMessage("删除失败");
            logger.error("车辆库存资源删除", e);
        }

        return resultData;
    }

    @Override
    public ResultData getUserInfo(String userName, String permit) {
        ResultData resultData = new ResultData("false", null, null);
        try {
            List a = new ArrayList();
            a.add(用户Repository.findOneByEmail(permit, userName));
            resultData.setPageData(new PageData(a, 0));
            resultData.setResult("true");
        } catch (Exception e) {

            resultData.setMessage("删除失败");
            logger.error("车辆库存资源删除", e);
        }

        return resultData;
    }
    @Override
    public Map getCustomerLeaveState(String userName, String permit, Integer custenterid) {
        Map result =new HashMap();
        try {
            顾客进店记录表Model model顾客进店记录表 = repository顾客进店记录表.findOne(custenterid);
            临时接待记录Model model临时接待记录=teampRecepRepository.findOne(custenterid);
            DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            DateFormat sd = new SimpleDateFormat("yyyy-MM-dd");

            if (model顾客进店记录表!= null &&DateFormatUtils.isNoStore(model顾客进店记录表.get到店时间())) {
                result.put("message","成功");
                result.put("state","0");
                result.put("result","true");
                return  result;
            }
            //Time leaveTime=new Time (sdf.parse(DefaultValueConstant.Customer_Leave_State_Time).getTime() );
            Date now=new Date();
            String a=sd.format(now);
            Date leaveTime=sdf.parse(a+" "+DefaultValueConstant.Customer_Leave_State_Time) ;


            //如果离店时间为  空  且 当前时间 晚于  17:30则  则返回  状态为1  显示设置离店时间按钮；
            if (model顾客进店记录表!= null && model顾客进店记录表.get离店时间()==null&&now.after(leaveTime)){
                result.put("message","成功");
                result.put("state","1");
                result.put("result","true");
                return  result;
            }
            //前台推过来  且 结束接待时间为空
            if (model顾客进店记录表 == null && model临时接待记录 != null && model临时接待记录.get结束接待时间()==null && now.after(leaveTime)){
                result.put("message","成功");
                result.put("state","1");
                result.put("result","true");
                return  result;
            }
            result.put("message","成功");
            result.put("state","0");
            result.put("result","true");
            return  result;

        } catch (Exception e) {
            result.put("message","数据异常，查询失败");
            result.put("state","0");
            result.put("result","false");
            logger.error("itask离店按钮显示失败", e);
        }
        return result;
    }

    @Override
    public Map saveLeaveTime(String userName, String permit, SaveLeaveTime laveTimeInfo) {
        Map result =new HashMap();
        try {
            顾客进店记录表Model model顾客进店记录表 = repository顾客进店记录表.findOne(laveTimeInfo.custenterid);
            临时接待记录Model model临时接待记录=teampRecepRepository.findOne(laveTimeInfo.custenterid);
            DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            DateFormat sds = new SimpleDateFormat("HH:mm:ss");
            DateFormat sd = new SimpleDateFormat("yyyy-MM-dd");

            if(model临时接待记录!=null && model临时接待记录.get开始试驾时间()!=null){
                //如果试驾结束时间为空
                if (model临时接待记录.get结束试驾时间()==null){
                    //请先输入试驾结束时间、才能离店
                    result.put("message","请先输入试驾结束时间，才能离店");
                    result.put("result","false");
                    return  result;
                }else if (model临时接待记录.get结束试驾时间()!=null){
                    //离店时间
                    Time LeaTime = new Time(sds.parse(laveTimeInfo.leaveTime).getTime());
                    //试驾结束时间
                    Time SJendTime  =model临时接待记录.get结束试驾时间();
                    //离店时间不得早于试驾结束时间
                    if(LeaTime.before(SJendTime)){
                        result.put("message","离店时间不得早于试驾结束时间");
                        result.put("result","false");
                        return  result;
                    }
                }
            }

            if (model顾客进店记录表 != null && DateFormatUtils.isNoStore(model顾客进店记录表.get到店时间())) {
                result.put("message","无进店记录、未进店或大客户不予设置");
                result.put("result","false");
                return  result;
            }
            Time inputLeaveTime=new Time (sds.parse(laveTimeInfo.leaveTime).getTime() );
            Date now=new Date();
            String a=sd.format(now);
            Date leaveTime=sdf.parse(a+" "+DefaultValueConstant.Customer_Leave_State_Time) ;
            Time enterTime=null;
            if (model顾客进店记录表!=null){
                  enterTime =model顾客进店记录表.get到店时间();
            }  else{
                 enterTime =model临时接待记录.get开始接待时间();
            }
            //如果离店时间为  空  且 当前时间 晚于  17:30则  则返回  状态为1  显示设置离店时间按钮；
            if (model顾客进店记录表 != null &&model顾客进店记录表.get离店时间()==null&&now.after(leaveTime)){
                if( inputLeaveTime.before(enterTime)){
                    result.put("message","输入离店日期不能早于进店日期");
                    result.put("result","false");
                    return  result;
                }
                model顾客进店记录表.set离店时间(inputLeaveTime);
                model顾客进店记录表.set操作人(userName);
                model顾客进店记录表.set更新账号(userName);
                model顾客进店记录表.get到店时间();
               //计算客户停留时间 （离店时间减去进店时间，精确到分钟）
                Long staydate=(inputLeaveTime.getTime()-enterTime.getTime())/(1000*60);
                Integer StayTime=Integer.parseInt(staydate.toString());
                model顾客进店记录表.set停留时间(StayTime);

                repository顾客进店记录表.save(model顾客进店记录表);
                result.put("message","离店成功");
                result.put("result","true");
                return  result;
            }
            //离店时间为空 且 前台为下班  提示
            else if(model顾客进店记录表 != null &&model顾客进店记录表.get离店时间()==null&&!now.after(leaveTime)){
                result.put("message","前台还未下班，请让前台设置");
                result.put("result","false");
                return  result;
            }
            // 离店时间不为空
            else if(model顾客进店记录表 != null &&model顾客进店记录表.get离店时间()!=null){
                model顾客进店记录表.get操作人();
                String name=  用户Repository.findNameBy许可And用户名(permit,userName);
                result.put("message","用户："+name+" 已经操作");
                result.put("result","false");
                return  result;
            }
            //前台推送  且进店记录录表中不存在   修改 临时接待几录
            else if(model顾客进店记录表 == null&&model临时接待记录!=null ){

                if( inputLeaveTime.before(enterTime)){
                    result.put("message","输入离店日期不能早于进店日期");
                    result.put("result","false");
                    return  result;
                }

                model临时接待记录.set结束接待时间(inputLeaveTime);
                model临时接待记录.set是否接待完成("是");
                teampRecepRepository.save(model临时接待记录);
                result.put("message","离店成功");
                result.put("result","true");
                return  result;
            }
            result.put("message","离店成功");
            result.put("result","true");
            return  result;

        } catch (Exception e) {
            result.put("message","数据异常，保存失败");
            result.put("result","false");
            logger.error("离店时间保存失败", e);
        }
        return result;
    }

    private boolean isChineseLanguage(){
        return "CN".equalsIgnoreCase(ThreadContext.get("LIVE_LANGUAGE"));
    }

    @Override
    public ResultData getgetInfrastructure(List<Itask基础设置Model> modelList){
       ResultData result = new ResultData();
      try {
          // 返回给前端的 格式为：
          // 设置项目：数据库手续费统一格式为：（1）上牌服务费成本（2）其他一成本（3）其他二成本
          // 值的格式为： 成本__5000.00   比例__0.3333
          // 通过 成本__和 比例__ 来区分  服务费成本 和 服务费成本比例
          List<Map> list = new ArrayList();
          DecimalFormat df = new DecimalFormat("#.00");

          for (Itask基础设置Model ITModel:modelList) {
              Itask基础设置Model Dao =new Itask基础设置Model();
              Itask基础设置ModelPK model1 = new Itask基础设置ModelPK();
              Dao.set许可(ITModel.get许可());
              model1.set许可(Dao.get许可());
              Dao.set设置项目(ITModel.get设置项目());

              // 前端传值过来，要进行转换 才能在数据库查到数据
              if ("上牌服务费成本比例".equals(ITModel.get设置项目())){
                  Dao.set设置项目("上牌服务费成本");
              }else if ("其他一成本比例".equals(ITModel.get设置项目())){
                  Dao.set设置项目("其他一成本");
              }else if ("其他二成本比例".equals(ITModel.get设置项目())){
                  Dao.set设置项目("其他二成本");
              }

              model1.set设置项目(Dao.get设置项目());
              Itask基础设置Model itask = itask基础设置Repository.findOne(model1);

              Map map = new HashMap();
              if (itask!=null
                      && !Strings.isNullOrEmpty(itask.get值())
                      && !Strings.isNullOrEmpty(itask.get设置项目())){

                // String aa = itask.get值().substring(0,2);
                  Itask基础设置Model modelDao =new Itask基础设置Model();
                  if ("成本".equals(itask.get值().substring(0,2))){
                      String zhi = itask.get值().substring(4,itask.get值().length());
                      modelDao.set值(zhi);
                      modelDao.set设置项目(itask.get设置项目());

                  }else{
                      String zhi = itask.get值().substring(4,itask.get值().length());
                      Double dou = Double.parseDouble(zhi)*100;
                      modelDao.set值(df.format(dou).toString());
                      modelDao.set设置项目(itask.get设置项目());

                      if ("上牌服务费成本".equals(itask.get设置项目())){
                          modelDao.set设置项目("上牌服务费成本比例");
                      }else if ("其他一成本".equals(itask.get设置项目())){
                          modelDao.set设置项目("其他一成本比例");
                      }else if ("其他二成本".equals(itask.get设置项目())){
                          modelDao.set设置项目("其他二成本比例");
                      }
                  }


                  map.put("值",modelDao.get值());
                  map.put("设置项目",modelDao.get设置项目());
                  list.add(map);
              }
          }
          if (list!=null && list.size()!=0){
              result.setResult("true");
              result.setPageData(new PageData(list,list.size()));
          }else {
              result.setResult("flase");
              result.setMessage("还没设置手续费");
          }

      }catch (Exception e){
          e.printStackTrace();
          result.setResult("flase");
          result.setMessage("手续费查询失败");
          logger.error("查询手续费失败", e);
      }
       return result;
    }

    @Override
    public Object fillContractExcel(String fileName, String prodNum, String dlr) {
        logger.info("fillContractExcel参数为:" + prodNum);
        String errMsg = "fillContractExcel方法异常";
        InputStream inputStream = null;

        try {

            // 找到项目中的合同模版文件
            inputStream = this.getClass().getResourceAsStream("/templates/" + fileName);
            HSSFWorkbook workbook;
            try {
                // 以流方式初始化为workbook
                workbook = new HSSFWorkbook(inputStream);
            } catch (NotOfficeXmlFileException e) {
                errMsg = "导入非EXCEL文件，或者表格被另一程序打开或使用，请关闭该程序。";
                throw new Exception();
            } catch (IOException e) {
                errMsg = "fillContractExcel IO异常";
                throw new Exception();
            }
            // 找到对应sheet
            HSSFSheet sheet = workbook.getSheet("定购合同书");
            // 取得模版中需要的数据数据
            List data = this.repository.getContractData(prodNum);
            // 找不到对应数据
            if (data.size() == 0) {
                errMsg = "生产号为" + prodNum + "的车，暂时没有合同打印相关的数据";
                throw new Exception();
            }
            // 找到非法数据
            else if (data.size() > 1) {
                errMsg = "生产号为" + prodNum + "的车，返回多条合同打印数据";
                throw new Exception();
            }
            // 取唯一的合法数据
            else {
                Object obj = data.get(0);
                Map rawDataMap = (Map) obj;
                // 合同编号
                // 行索引
                CellReference rowRef = new CellReference("2");
                // 列索引
                CellReference colRef = new CellReference("ad");
                // 用行列引用定位单元格
                Cell conCode = sheet.getRow(rowRef.getRow()).getCell(colRef.getCol());
                conCode.setCellValue((String) rawDataMap.get("contract_code"));

                // 定购方区域
                // 登记名义人
                Cell registerName = sheet.getRow(new CellReference("5").getRow())
                        .getCell(new CellReference("e").getCol());
                registerName.setCellValue((String) rawDataMap.get("register_name"));
                // 性别
                Cell sex = sheet.getRow(new CellReference("5").getRow()).getCell(new CellReference("r").getCol());
                sex.setCellValue((String) rawDataMap.get("sex_1"));
                // 职业/行业
                /*Cell job = sheet.getRow(new CellReference("5").getRow()).getCell(new CellReference("w").getCol());
                job.setCellValue("model");*/
                // 移动电话，因为没有录入的地方，暂时用定购人的电话代替
                Cell cell = sheet.getRow(new CellReference("5").getRow()).getCell(new CellReference("ad").getCol());
                cell.setCellValue((String) rawDataMap.get("cell_1"));
                // 证件类型
                Cell idType = sheet.getRow(new CellReference("6").getRow()).getCell(new CellReference("e").getCol());
                idType.setCellValue((String) rawDataMap.get("id_type"));
                // 证件号码
                Cell idNum = sheet.getRow(new CellReference("6").getRow()).getCell(new CellReference("n").getCol());
                idNum.setCellValue((String) rawDataMap.get("id_num"));
                // 固定电话
                /*Cell tel = sheet.getRow(new CellReference("6").getRow()).getCell(new CellReference("ad").getCol());
                tel.setCellValue("8568");*/
                // 地址
                Cell address = sheet.getRow(new CellReference("7").getRow()).getCell(new CellReference("e").getCol());
                address.setCellValue((String) rawDataMap.get("address_1"));
                // 邮编
                Cell zipCode = sheet.getRow(new CellReference("7").getRow()).getCell(new CellReference("w").getCol());
                zipCode.setCellValue((String) rawDataMap.get("zipcode_1"));
                // E-mail
                Cell eMail = sheet.getRow(new CellReference("7").getRow()).getCell(new CellReference("ad").getCol());
                eMail.setCellValue((String) rawDataMap.get("email_1"));
                // 定购经办人
                Cell orderName = sheet.getRow(new CellReference("8").getRow()).getCell(new CellReference("e").getCol());
                orderName.setCellValue((String) rawDataMap.get("order_name"));
                // 性别2
                Cell sex2 = sheet.getRow(new CellReference("8").getRow()).getCell(new CellReference("r").getCol());
                sex2.setCellValue((String) rawDataMap.get("sex_2"));
                // 职业/行业2
                /*Cell job2 = sheet.getRow(new CellReference("8").getRow()).getCell(new CellReference("w").getCol());
                job2.setCellValue("model");*/
                // 移动电话2
                Cell cell2 = sheet.getRow(new CellReference("8").getRow()).getCell(new CellReference("ad").getCol());
                cell2.setCellValue((String) rawDataMap.get("cell_2"));
                // 证件类型2
                Cell idType2 = sheet.getRow(new CellReference("9").getRow()).getCell(new CellReference("e").getCol());
                idType2.setCellValue((String) rawDataMap.get("id_type_2"));
                // 证件号码2
                Cell idNum2 = sheet.getRow(new CellReference("9").getRow()).getCell(new CellReference("n").getCol());
                idNum2.setCellValue((String) rawDataMap.get("id_num_2"));
                // 固定电话2
                /*Cell tel2 = sheet.getRow(new CellReference("9").getRow()).getCell(new CellReference("ad").getCol());
                tel2.setCellValue("8568");*/
                // 地址2
                Cell address2 = sheet.getRow(new CellReference("10").getRow()).getCell(new CellReference("e").getCol());
                address2.setCellValue((String) rawDataMap.get("address_2"));
                // 邮编2
                Cell zipCode2 = sheet.getRow(new CellReference("10").getRow()).getCell(new CellReference("w").getCol());
                zipCode2.setCellValue((String) rawDataMap.get("zipcode_2"));
                // E-mail2
                Cell eMail2 = sheet.getRow(new CellReference("10").getRow()).getCell(new CellReference("ad").getCol());
                eMail2.setCellValue((String) rawDataMap.get("email_2"));

                // 车信息区域
                // 车名
                Cell carName = sheet.getRow(new CellReference("12").getRow()).getCell(new CellReference("c").getCol());
                carName.setCellValue((String) rawDataMap.get("car_name"));
                // 车型
                Cell carModel = sheet.getRow(new CellReference("12").getRow()).getCell(new CellReference("i").getCol());
                carModel.setCellValue((String) rawDataMap.get("car_model"));
                // 车架号码
                Cell carVin = sheet.getRow(new CellReference("12").getRow()).getCell(new CellReference("q").getCol());
                carVin.setCellValue((String) rawDataMap.get("vin"));
                // SFX
                Cell carSfx = sheet.getRow(new CellReference("12").getRow()).getCell(new CellReference("z").getCol());
                carSfx.setCellValue((String) rawDataMap.get("car_sfx"));
                // 颜色
                Cell carColor = sheet.getRow(new CellReference("12").getRow())
                        .getCell(new CellReference("ae").getCol());
                carColor.setCellValue((String) rawDataMap.get("car_color"));
                // 台数
                /*Cell carNum = sheet.getRow(new CellReference("12").getRow())
                .getCell(new CellReference("ai").getCol());
                carNum.setCellValue("壹");*/

                // 应付金额数据区域
                BigDecimal bd0 = new BigDecimal("0.00");
                List<BigDecimal> payableLi = new ArrayList<>();
                BigDecimal neatCarPrice = (BigDecimal) rawDataMap.get("neat_car_price"); // 净车价
                BigDecimal consumerTax = (BigDecimal) rawDataMap.get("consumer_tax"); // 消费税
                BigDecimal carTotal = (BigDecimal) rawDataMap.get("car_total"); // 车辆价格小计
                BigDecimal purchaseTax = (BigDecimal) rawDataMap.get("purchase_tax"); // 购置税
                BigDecimal vehicleVesselTax = (BigDecimal) rawDataMap.get("vehicle_vessel_tax"); // 车船税
                BigDecimal insuranceAmount = (BigDecimal) rawDataMap.get("insurance_amount"); // 保险金额
                BigDecimal licenseFee = (BigDecimal) rawDataMap.get("license_fee"); // 上牌费
                BigDecimal glassRepair = (BigDecimal) rawDataMap.get("glass_repair"); // 玻璃维修险
                BigDecimal theftRobbery = (BigDecimal) rawDataMap.get("theft_robbery"); // 盗抢险
                BigDecimal exInsuranceFee = (BigDecimal) rawDataMap.get("ex_insurance_fee"); // 延保费
                BigDecimal secondHand = (BigDecimal) rawDataMap.get("second_hand"); // 二手车置换
                BigDecimal loanFee = (BigDecimal) rawDataMap.get("loan_fee"); // 贷款服务费
                BigDecimal salesFee = (BigDecimal) rawDataMap.get("sales_fee"); // 销售服务费
                BigDecimal freebieFee = (BigDecimal) rawDataMap.get("freebie_fee"); // 精品费
                BigDecimal other = (BigDecimal) rawDataMap.get("other"); // 其他
                // 初始化需要填充的数据list
                payableLi.add(neatCarPrice == null ? bd0 : neatCarPrice);
                payableLi.add(consumerTax == null ? bd0 : consumerTax);
                payableLi.add(carTotal == null ? bd0 : carTotal);
                payableLi.add(purchaseTax == null ? bd0 : purchaseTax);
                payableLi.add(vehicleVesselTax == null ? bd0 : vehicleVesselTax);
                payableLi.add(insuranceAmount == null ? bd0 : insuranceAmount.subtract(vehicleVesselTax));
                payableLi.add(licenseFee == null ? bd0 : licenseFee);
                payableLi.add(glassRepair == null ? bd0 : glassRepair);
                payableLi.add(theftRobbery == null ? bd0 : theftRobbery);
                payableLi.add(exInsuranceFee == null ? bd0 : exInsuranceFee);
                payableLi.add(secondHand == null ? bd0 : secondHand);
                payableLi.add(loanFee == null ? bd0 : loanFee);
                payableLi.add(salesFee == null ? bd0 : salesFee);
                payableLi.add(freebieFee == null ? bd0 : freebieFee);
                payableLi.add(other == null ? bd0 : other);
                String[] payableTextArr = {"净车价", "消费税", "车辆价格小计", "购置税", "车船税", "保险金额", "上牌费",
                        "玻璃维修险", "盗抢险", "延保费", "二手车置换", "贷款服务费", "销售服务费", "精品费", "其他"};
                Integer maxLength9 = 9;
                String zero = "0";
                DecimalFormat df = new DecimalFormat("0.00");
                // 应付金额数据填充
                for (int i = 0; i < payableLi.size(); i++) {
                    // 格式化填充数据，保留两位小数，再将小数点去掉
                    String s = df.format(payableLi.get(i)).replace(".", "");
                    if (s.length() > maxLength9) {
                        errMsg = "应付金额" + payableTextArr[i] + "长度超出" + maxLength9 + "位，无法正常显示";
                        throw new Exception();
                    }
                    // 从r列开始往前面填数
                    for (int j = s.length() - 1; j >= 0; j--) {
                        Cell c = sheet.getRow(new CellReference(i + 15 + "").getRow())
                                .getCell(new CellReference((char) ('r' + (j - s.length() + 1)) + "").getCol());
                        c.setCellValue(s.charAt(j) + "");
                    }
                }
                // 应付合计，净车价，消费税不参与合计
                payableLi.set(0, bd0);
                payableLi.set(1, bd0);
                BigDecimal payableTotal = bd0;
                for (BigDecimal bd : payableLi) {
                    payableTotal = payableTotal.add(bd);
                }
                String strPayableTotal = df.format(payableTotal).replace(".", "");
                if (strPayableTotal.length() > maxLength9) {
                    errMsg = "应该金额合计超出" + maxLength9 + "位，无法正常显示";
                    throw new Exception();
                }
                // 合计数字串从最后一位开始往前遍历，同时将遍历字符填入EXCEL中R34开始往左的相应区域
                for (int j = strPayableTotal.length() - 1; j >= 0; j--) {
                    Cell tmp = sheet.getRow(new CellReference("34").getRow())
                            .getCell(new CellReference((char) ('r' + (j - strPayableTotal.length() + 1)) + "").getCol());
                    tmp.setCellValue(Integer.parseInt(strPayableTotal.charAt(j) + ""));
                }
                // 合计（大写金额），把合计以阿拉伯数据填入合并后的合计（大写金额），修改其格式为特殊-人民币大写
                Cell totalCn = sheet.getRow(new CellReference("35").getRow()).getCell(new CellReference("e").getCol());
                totalCn.setCellValue(Double.parseDouble(df.format(payableTotal)));

                // 精品区域
                Integer maxLength8 = 8;
                // 获取相应的精品数据
                List freebieLi = this.repository.getContractDataFreebies(prodNum);
                if (freebieLi.size() > 20) {
                    errMsg = "精品数量超出20，无法正常显示";
                    throw new Exception();
                }
                for (int i = 0; i < freebieLi.size(); i++) {
                    CellReference row = new CellReference(16 + i + "");
                    Cell freebieName = sheet.getRow(row.getRow()).getCell(new CellReference("v").getCol());
                    String fName = (String) ((Map) freebieLi.get(i)).get("freebie_name");
                    freebieName.setCellValue(fName);
                    Cell quantity = sheet.getRow(row.getRow()).getCell(new CellReference("ab").getCol());
                    quantity.setCellValue((Integer) ((Map) freebieLi.get(i)).get("quantity"));
                    // 精品标准售价
                    String s;
                    if (((Map) freebieLi.get(i)).get("dis_price") == null) {
                        s = zero;
                    } else {
                        s = df.format(((Map) freebieLi.get(i)).get("dis_price")).replace(".", "");
                    }
                    if (s.length() > maxLength8) {
                        errMsg = "精品" + fName + "折后价超出8位，无法正常显示";
                        throw new Exception();
                    }
                    for (int j = s.length() - 1; j >= 0; j--) {
                        Cell tmp = sheet.getRow(row.getRow()).getCell(36 + (j - s.length() + 1)); // ak~ad列
                        tmp.setCellValue(Integer.parseInt(s.charAt(j) + ""));
                    }
                }
                // 原价合计
                BigDecimal oriPrice = new BigDecimal("0");
                String strOriPrice;
                for (Object object : freebieLi) {
                    Map map = (Map) object;
                    if (map.get("ori_price") != null) {
                        oriPrice = oriPrice.add((BigDecimal) map.get("ori_price"));
                    }
                }
                strOriPrice = df.format(oriPrice).replace(".", "");
                if (strOriPrice.length() > maxLength8) {
                    errMsg = "精品原价合计超出" + maxLength8 + "位，无法正常显示";
                    throw new Exception();
                }
                for (int i = strOriPrice.length() - 1; i >= 0; i--) {
                    Cell c = sheet.getRow(new CellReference("36").getRow()).getCell(36 + (i - strOriPrice.length() + 1));
                    c.setCellValue(Integer.parseInt(strOriPrice.charAt(i) + ""));
                }
                // 折后合计
                BigDecimal disPrice = new BigDecimal("0");
                String strDisPrice;
                for (Object object : freebieLi) {
                    Map map = (Map) object;
                    if (map.get("dis_price") != null) {
                        disPrice = disPrice.add((BigDecimal) map.get("dis_price"));
                    }
                }
                strDisPrice = df.format(disPrice).replace(".", "");
                if (strDisPrice.length() > maxLength8) {
                    errMsg = "精品折后价合计超出" + maxLength8 + "位，无法正常显示";
                    throw new Exception();
                }
                for (int i = strDisPrice.length() - 1; i >= 0; i--) {
                    Cell c = sheet.getRow(new CellReference("37").getRow()).getCell(36 + (i - strDisPrice.length() + 1));
                    c.setCellValue(Integer.parseInt(strDisPrice.charAt(i) + ""));
                }
                // 定金
                String orderAmount;
                if (rawDataMap.get("order_amount") == null) {
                    orderAmount = zero;
                } else {
                    orderAmount = df.format(rawDataMap.get("order_amount")).replace(".", "");
                    if (orderAmount.length() > maxLength9) {
                        errMsg = "定金超出9位，无法正常显示";
                        throw new Exception();
                    }
                }
                for (int i = orderAmount.length() - 1; i >= 0; i--) {
                    Cell tmp = sheet.getRow(new CellReference("37").getRow()).getCell(new CellReference((char) ('r' + (i - orderAmount.length() + 1)) + "").getCol());
                    tmp.setCellValue(Integer.parseInt(orderAmount.charAt(i) + ""));
                }
                // 置换旧车价格
                String secondHandPrice;
                if (rawDataMap.get("second_hand_price") == null) {
                    secondHandPrice = zero;
                } else {
                    secondHandPrice = df.format(rawDataMap.get("second_hand_price")).replace(".", "");
                    if (secondHandPrice.length() > maxLength9) {
                        errMsg = "置换旧车价格超出9位，无法正常显示";
                        throw new Exception();
                    }
                }
                for (int i = secondHandPrice.length() - 1; i >= 0; i--) {
                    Cell tmp = sheet.getRow(new CellReference("38").getRow()).getCell(new CellReference((char) ('r' + (i - secondHandPrice.length() + 1)) + "").getCol());
                    tmp.setCellValue((Integer.parseInt(secondHandPrice.charAt(i) + "")));
                }
                // 余款合计
                BigDecimal balance = new BigDecimal(strPayableTotal);
                balance = balance.subtract(new BigDecimal(orderAmount));
                balance = balance.subtract(new BigDecimal(secondHandPrice));
                String strBalance = balance.toString();
                for (int j = strBalance.length() - 1; j >= 0; j--) {
                    Cell c = sheet.getRow(new CellReference("39").getRow()).getCell(new CellReference((char) ('r' + (j - strBalance.length() + 1)) + "").getCol());
                    c.setCellValue(strBalance.charAt(j) + "");
                }
                // 经销商名
                Cell dealerName = sheet.getRow(new CellReference("59").getRow()).getCell(new CellReference("c").getCol());
                dealerName.setCellValue((String) rawDataMap.get("dealer_name"));
                // 经销商地址
                Cell dealerAddress = sheet.getRow(new CellReference("60").getRow()).getCell(new CellReference("f").getCol());
                dealerAddress.setCellValue((String) rawDataMap.get("dealer_address"));
                // 经销商电话
                Cell dealerTel = sheet.getRow(new CellReference("60").getRow()).getCell(new CellReference("o").getCol());
                dealerTel.setCellValue((String) rawDataMap.get("dealer_tel"));
                // 登记名义人副本
                Cell registerNameCp = sheet.getRow(new CellReference("59").getRow()).getCell(new CellReference("y").getCol());
                registerNameCp.setCellValue((String) rawDataMap.get("register_name"));
                // 定购经办人副本
                Cell orderNameCp = sheet.getRow(new CellReference("60").getRow()).getCell(new CellReference("y").getCol());
                orderNameCp.setCellValue((String) rawDataMap.get("order_name"));
                // 定购日期
                String orDate = LocalDate.now().toString();
                Cell orderDateYear = sheet.getRow(new CellReference("63").getRow()).getCell(new CellReference("y").getCol());
                orderDateYear.setCellValue(Integer.parseInt(orDate.substring(0, 4)));
                Cell orderDateMonth = sheet.getRow(new CellReference("63").getRow()).getCell(new CellReference("ae").getCol());
                orderDateMonth.setCellValue(Integer.parseInt(orDate.substring(5, 7)));
                Cell orderDateDay = sheet.getRow(new CellReference("63").getRow()).getCell(new CellReference("ag").getCol());
                orderDateDay.setCellValue(Integer.parseInt(orDate.substring(8, 10)));
                // 打印日期
                Cell printDt = sheet.getRow(new CellReference("64").getRow()).getCell(new CellReference("c").getCol());
                printDt.setCellValue(orDate);
                // 销售员
                Cell sc = sheet.getRow(new CellReference("64").getRow()).getCell(new CellReference("n").getCol());
                sc.setCellValue((String) rawDataMap.get("sc_name"));
            }
            // 返回数据

            return workbook;
        } catch (Exception e) {
            logger.error(errMsg, e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new ResultData("false", errMsg, null);
        }finally{
            if(inputStream != null){
                try {
                    inputStream.close();
                }catch (Exception exc){
                    logger.error("合同打印异常", exc);
                }
            }
        }
    }

    @Override
    public PageData getInventoryInfo(String dealer, Map map, RequestBase request) {
        return repository.getInventoryInfo(dealer, map, request);
    }

    @Override
    public ResultData getSaleTailAfter(String permit,SaleTailAfter request, RequestBase RBase) {
        ResultData result = new ResultData("false",null,null);
        try {
            result.setResult("true");
            result.setMessage("调车跟踪查询成功");
            result.setPageData(repository.getSaleTailAfter(permit,request,RBase));
        }catch(Exception e){
            e.printStackTrace();
            logger.error("调车跟踪查询失败: ", e);
            result.setResult("false");
            result.setMessage("调车跟踪查询成功");
            return result;
        }
        return result;
    }
    @Override
    public void ExportSaleTailAfter(String dealer, Map map, RequestBase request, OutputStream outputStream) {
        try {
            ExcelReportContext context = new ExcelReportContext();
            String[] columns = map.get("columns").toString().split("[|]");
            map.remove("columns");
            context.setTemplate("templates/销售行政车辆调出调入跟踪导出模板.xlsx")
                    .setFileName("销售行政车辆调出调入跟踪导出模板.xlsx")
                    .setSource(exportSaleTailAfter)
                    .setStaticSheet(false)
                    .setStartCellIndex(0)
                    .setEndCellIndex(columns.length)
                    .setAutoRowExtended(true)
                    .addParam("dealer", dealer)
                    .addParam("param", map)
                    .addParam("columns", columns)
                    .addParam("request", request);

            excelReportService.export(context, outputStream);
        } catch (Exception e) {
            logger.error("销售行政车辆调出调入跟踪导出模板导出异常", e);
        }
    }

    @Override
    public void exportInventoryInfo(String dealer, Map map, RequestBase request, OutputStream outputStream) {
        try {
            ExcelReportContext context = new ExcelReportContext();
            String[] columns = map.get("columns").toString().split("[|]");
            map.remove("columns");
            context.setTemplate("templates/销售行政标准导出模板.xlsx")
                    .setFileName("经销商 销售行政标准导出模板.xlsx")
                    .setSource(exportInventorySource)
                    .setStaticSheet(false)
                    .setStartCellIndex(0)
                    .setEndCellIndex(columns.length)
                    .setAutoRowExtended(true)
                    .addParam("dealer", dealer)
                    .addParam("param", map)
                    .addParam("columns", columns)
                    .addParam("request", request);

            excelReportService.export(context, outputStream);
        } catch (Exception e) {
            logger.error("导出线索信息异常", e);
        }
    }


    //根据生产号查出详细信息
    public PageData getInfoByProudctionId(String pid, HttpServletRequest request){
        PageData pageData = repository.getInfoByProudctionId(pid,request);
        if (null != pageData) {
            if (null != pageData.getData() && !pageData.getData().isEmpty()) {
                Map map = (Map) pageData.getData().get(0);
                if (null == map.get("报价编号")) {
                    map.put("实收金额",null);
                } else {
                    报价单表Model quotedModel = i报价单表Repository.findOne((Integer) map.get("报价编号"));
                    String actualReceiveMoney = 销售财务表Repository.getActualReceiveMoney(quotedModel.get初始报价单号());
                    map.put("实收金额",actualReceiveMoney);
                }
            }
        }
        return pageData;
    }

    @Override
    public ResultData getOrders(String dlr, GetOrdersRequest req) {
        logger.info("getOrders传入参数为:" + JsonObjectUtils.writeAsJson(req));
        PageData pageData = this.repository.getOrders(dlr, req);
        calculateGp(pageData.getData());
        return new ResultData("true", null, pageData);
    }

    @Override
    public ResultData getOrdersHistory(String originId) {
        logger.info("getOrdersHistory传入参数为:" + originId);
        List list = this.repository.getOrdersHistory(originId);
        calculateGp(list);
        return new ResultData("true", null, new PageData(list, list.size()));
    }

    @Override
    public ResultData getOrdersReview(Integer qNum) {
        logger.info("getOrdersReview:" + qNum);
        List list = this.repository.getOrdersReview(qNum);
        if (list != null && !list.isEmpty()) {
            Map map = (Map) list.get(0);
            报价单表Model quotedModel = i报价单表Repository.findOne(qNum);
            String actualReceiveMoney = 销售财务表Repository.getActualReceiveMoney(quotedModel.get初始报价单号());
            map.put("实收金额",actualReceiveMoney);
        }
        return new ResultData("true", null, new PageData(list, list.size()));
    }

    @Override
    public void calculateGp(List list) {
        // todo 缺少收入调整
        for (Object obj : list) {
            Map<String, Object> map = (Map) obj;
            DecimalFormat df = new DecimalFormat("0.00");
            BigDecimal tax17 = new BigDecimal("1.17");
            BigDecimal tax06 = new BigDecimal("1.06");
            BigDecimal hundred = new BigDecimal("100");
            BigDecimal zero = new BigDecimal("0");
            Integer scale = 7;
            Integer roundMode = BigDecimal.ROUND_HALF_EVEN;
            BigDecimal 车辆销售价 = (BigDecimal) map.get("车辆销售价");
            BigDecimal 采购价格含税 = (BigDecimal) map.get("采购价格（含税）");
            BigDecimal 消费税及附加 = (BigDecimal) map.get("消费税及附加");
            BigDecimal gp1 = 车辆销售价
                    .subtract(采购价格含税)
                    .subtract(消费税及附加)
                    .divide(tax17, scale, roundMode);
            BigDecimal da = 车辆销售价.subtract(消费税及附加).divide(tax17, scale, roundMode); // 第一种分母
            BigDecimal gp1p;
            if (da.compareTo(zero) == 0) {
                gp1p = zero;
            } else {
                gp1p = gp1.divide(da, scale, roundMode).multiply(hundred);
            }
            map.put("GP1", df.format(gp1));
            map.put("GP1%", df.format(gp1p));

            BigDecimal 经销商随车成本不含精品延保 = (BigDecimal) map.get("经销商随车成本不含精品延保");
            BigDecimal 随车精品成本 = (BigDecimal) map.get("随车精品成本");
//            BigDecimal 随车延保成本 = (BigDecimal) map.get("随车延保成本");
            BigDecimal 随车厂家延保成本 = (BigDecimal) map.get("随车厂家延保成本");
            BigDecimal 随车第三方延保成本 = (BigDecimal) map.get("随车第三方延保成本");
            BigDecimal 经销商随车成本 = 经销商随车成本不含精品延保
                    .add(随车精品成本.divide(tax17, scale, roundMode))
                    .add(随车厂家延保成本.divide(tax17, scale, roundMode))
                    .add(随车第三方延保成本.divide(tax17, scale, roundMode))/*.add(随车延保成本)*/;
//            BigDecimal 厂家非购置税随车成本 = (BigDecimal) map.get("厂家非购置税随车成本");
//            BigDecimal 贴息金额 = (BigDecimal) map.get("贴息金额");
            BigDecimal gp2 = gp1.subtract(经销商随车成本)/*.subtract(厂家非购置税随车成本).subtract(贴息金额)*/;
            BigDecimal gp2p;
            if (da.compareTo(zero) == 0) {
                gp2p = zero;
            } else {
                gp2p = gp2.divide(da, scale, roundMode).multiply(hundred);
            }
            map.put("GP2", df.format(gp2));
            map.put("GP2%", df.format(gp2p));

            BigDecimal 厂家零售SI = (BigDecimal) map.get("厂家零售SI");
            BigDecimal 厂家批售SI = (BigDecimal) map.get("厂家批售SI");
//            BigDecimal 厂家SI_购置税成本 = (BigDecimal) map.get("厂家SI_购置税成本");
            BigDecimal gp3 = gp2.add(厂家零售SI).add(厂家批售SI)/*.add(厂家SI_购置税成本)*/;
            BigDecimal gp3p;
            if (da.compareTo(zero) == 0) {
                gp3p = zero;
            } else {
                gp3p = gp3.divide(da, scale, roundMode).multiply(hundred);
            }
            map.put("GP3", df.format(gp3));
            map.put("GP3%", df.format(gp3p));

            BigDecimal 现金销售精品产品毛利 = (BigDecimal) map.get("现金销售精品产品毛利");
            BigDecimal 金融手续费 = (BigDecimal) map.get("金融手续费");
            BigDecimal 金融服务费 = (BigDecimal) map.get("金融服务费");
            BigDecimal 新保手续费 = (BigDecimal) map.get("新保手续费");
            BigDecimal 盗抢险手续费 = (BigDecimal) map.get("盗抢险手续费");
            BigDecimal 现金销售厂家延保延保毛利 = (BigDecimal) map.get("现金销售厂家延保延保毛利");
            BigDecimal 现金销售本店第三方延保毛利 = (BigDecimal) map.get("现金销售本店第三方延保毛利");
            BigDecimal 延保毛利 = 现金销售厂家延保延保毛利.add(现金销售本店第三方延保毛利);
            BigDecimal 置换手续费 = (BigDecimal) map.get("置换手续费");
            BigDecimal 上牌服务费 = (BigDecimal) map.get("上牌服务费");
            BigDecimal 上牌服务费成本 = (BigDecimal) map.get("上牌服务费成本");
            BigDecimal 其他一毛利 = (BigDecimal) map.get("其他一毛利");
            BigDecimal 其他二毛利 = (BigDecimal) map.get("其他二毛利");
            BigDecimal 销售服务费 = (BigDecimal) map.get("销售服务费");
            BigDecimal 其他三毛利 = (BigDecimal) map.get("其他三毛利");
            BigDecimal 其他四毛利 = (BigDecimal) map.get("其他四毛利");
            BigDecimal 其他五毛利 = (BigDecimal) map.get("其他五毛利");

            BigDecimal gp4d5 = gp3
                    .add(现金销售精品产品毛利)
                    .add(金融手续费.divide(tax06, scale, roundMode))
                    .add(金融服务费.divide(tax17, scale, roundMode))
                    .add(新保手续费.divide(tax06, scale, roundMode))
                    .add(盗抢险手续费.divide(tax06, scale, roundMode))
                    .add(延保毛利)
                    .add(置换手续费.divide(tax06, scale, roundMode))
                    .add(上牌服务费.subtract(上牌服务费成本).divide(tax17, scale, roundMode))
                    .add(其他一毛利)
                    .add(其他二毛利)
                    .add(销售服务费.divide(tax17, scale, roundMode))
                    .add(其他三毛利)
                    .add(其他四毛利)
                    .add(其他五毛利);

            BigDecimal 精品销售总价 = (BigDecimal) map.get("精品销售总价");
            BigDecimal 厂家延保实收金额 = (BigDecimal) map.get("厂家延保实收金额(含税)");
            BigDecimal 第三方延保实收金额 = (BigDecimal) map.get("第三方延保实收金额(含税)");

            BigDecimal db = 车辆销售价.divide(tax17, scale, roundMode) // 第二种分母
                    .subtract(消费税及附加.divide(tax17, scale, roundMode))
                    .add(精品销售总价.divide(tax17, scale, roundMode))
                    .add(厂家延保实收金额.divide(tax17, scale, roundMode))
                    .add(第三方延保实收金额.divide(tax17, scale, roundMode))
                    .add(金融手续费.divide(tax06, scale, roundMode))
                    .add(金融服务费.divide(tax17, scale, roundMode))
                    .add(新保手续费.divide(tax06, scale, roundMode))
                    .add(盗抢险手续费.divide(tax06, scale, roundMode))
                    .add(上牌服务费.subtract(上牌服务费成本).divide(tax17, scale, roundMode))
                    .add(其他一毛利)
                    .add(其他二毛利)
                    .add(销售服务费.divide(tax17, scale, roundMode))
                    .add(其他三毛利)
                    .add(其他四毛利)
                    .add(其他五毛利);
            BigDecimal gp4d5p;
            if (db.compareTo(zero) == 0) {
                gp4d5p = zero;
            } else {
                gp4d5p = gp4d5.divide(db, scale, roundMode).multiply(hundred);
            }
            map.put("Sales T.GP", df.format(gp4d5));
            map.put("Sales T.GP%", df.format(gp4d5p));
            map.put("GP4.5", df.format(gp4d5));
            map.put("GP4.5%", df.format(gp4d5p));
            // 新保手续费，除去税
            map.put("新保手续费",新保手续费.divide(tax06, scale, roundMode)); // 新保手续费 =（交强险手续费 + 商业险手续费）/1.06
            map.put("上牌服务费", 上牌服务费.subtract(上牌服务费成本).divide(tax17, scale, roundMode));
            map.put("经销商随车成本", 经销商随车成本不含精品延保.add(随车精品成本));
        }
    }

    @Override
    public void exportOrder(String dealer, Map map, RequestBase request, OutputStream outputStream) {
        try {
            ExcelReportContext context = new ExcelReportContext();
            String[] columns = map.get("columns").toString().split("[|]");
            map.remove("columns");
            context.setTemplate("templates/销售行政订单导出模板.xlsx")
                    .setFileName("经销商 销售行政订单导出模板.xlsx")
                    .setSource(exportOrderSource)
                    .setStaticSheet(false)
                    .setStartCellIndex(0)
                    .setEndCellIndex(columns.length)
                    .setAutoRowExtended(true)
                    .addParam("dealer", dealer)
                    .addParam("param", map)
                    .addParam("columns", columns)
                    .addParam("request", request);
            excelReportService.export(context, outputStream);
        } catch (Exception e) {
            logger.error("导出订单信息异常", e);
        }
    }

    @Override
    public ResultData boutiqueContract(String dealer,Map map,HttpServletResponse response) {
        ResultData result = new ResultData();
        try {
            String cc= "精品编号,精品编号|精品名称,精品名称|数量,数量|单位,单位|单价,单价|金额,金额|工时,工时|领料人员,领料人员|施工人员,施工人员|质检,质检|完检,完检|备注,备注";
            ExcelReportContext context = new ExcelReportContext();
            String[] columns = cc.split("[|]");
            map.remove("columns");
            context.setTemplate("templates/经销商_精品明细导出模板.xlsx")
                    .setFileName("经销商 经销商_精品明细导出模板.xlsx")
                    .setSource(ExportBoutiqueContract)
                    .setStaticSheet(false)
                    .setStartCellIndex(0)
                    .setEndCellIndex(columns.length + 1)
                    .setAutoRowExtended(true)
                    .addParam("dealer", dealer)
                    .addParam("param", map)
                    .addParam("columns", columns);

            excelReportService.export(context, response.getOutputStream());
            result.setResult("true");
            result.setMessage("精品明细合同模版导出成功");
        } catch (Exception e) {
            logger.error("精品明细合同模版导出失败,boutiqueContract", e);
            result.setResult("false");
            result.setMessage("精品合同模版导出失败");
        }
        return result;
    }
}

